-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make System.Formats.Nrbf public #103232
Make System.Formats.Nrbf public #103232
Conversation
- rename the folders, project and solution files - rename the namespace - set IsPackable to true and reference the project, not the source files
- PayloadReader -> NrbfDecoder - ArrayRecord<T> -> SZArrayRecord<T> - Read -> Decode
…rt for custom offset arrays
Tagging subscribers to this area: @dotnet/area-system-security, @bartonjs, @vcsjones |
- introduce SerializationRecord.TypeName, remove ArrayRecord.ElementType - rename IsTypeNameMatching to TypeNameMatches, make it non-virtual and ignore assembly names - remove type-forwarding logic, use it only for testing cc @jkotas
…nstraint, re-add all values present in the NRBF spec
{ | ||
int id = reader.ReadInt32(); | ||
|
||
if (id == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0
is the only illegal value. It allowed me to avoid the need of introducing Null
property, as all IsNull
checks are now Equals(default)
I know it's less pretty, but this is the API that got approved and TBH 99.99% of users should not use it at all.
_ => throw new NotSupportedException(), | ||
}; | ||
|
||
[RequiresUnreferencedCode("Calls System.Windows.Forms.BinaryFormat.BinaryFormattedObject.TypeResolver.GetType(TypeName)")] | ||
internal static Array? GetSimpleBinaryArray(ArrayRecord arrayRecord, BinaryFormattedObject.ITypeResolver typeResolver) | ||
{ | ||
if (arrayRecord.ArrayType is not (BinaryArrayType.Single or BinaryArrayType.Jagged or BinaryArrayType.Rectangular)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these types are now simply rejected by the decoder itself
|
||
// Keeping a separate stack for ids for fast infinite loop checks. | ||
private readonly Stack<int> _parseStack = []; | ||
private readonly Stack<SerializationRecordId> _parseStack = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will significantly hurt performance for deep graphs if SerializationRecordId
is not RuntimeHelpers.IsBitwiseEquatable<T>()
. If it isn't, or can't be made so, we should allow getting the raw value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PTAL at daa7431, I think I was able to remove the need for having this separate stack
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can just throw there.
/// <summary> | ||
/// The ID of <see cref="SerializationRecord" />. | ||
/// </summary> | ||
public readonly struct SerializationRecordId : IEquatable<SerializationRecordId> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment about bitwise-equality: https://github.com/dotnet/runtime/pull/103232/files/a171648cfff83059d12b0021fc162bea9d67de5b#r1635270940
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adamsitnik, @GrabYourPitchforks overriding GetHashCode
or Equals
makes this id not bitwise equatable from the runtime's perspective. This makes searching for existing ids in arrays suboptimal. Is there a reason we can't expose the underlying value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes searching for existing ids in arrays suboptimal.
But with my latest changes (daa7431) we don't need to do that anymore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @bartonjs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overriding GetHashCode or Equals makes this id not bitwise equatable from the runtime's perspective
That just because we have not implemented general bitwise equatable optimization in the runtime. I would be best to avoid introducing workarounds for that in public API designs. Instead, add ref-counts to the general bitwise equatable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adamsitnik we don't for that specific usage, but other usages would hurt.
@jkotas I'm not sure what you mean? Can you point out the general bitwise equatable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue that I have linked in my comment has the design discussion about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jkotas, sorry I misunderstood your comment. I thought there was some sort of internal back door, not that we needed to add links to the existing issue. :)
src/libraries/System.Formats.Nrbf/ref/System.Formats.Nrbf.csproj
Outdated
Show resolved
Hide resolved
src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySinglePrimitiveRecord.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySingleObjectRecord.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySingleStringRecord.cs
Outdated
Show resolved
Hide resolved
I do not have any more comments, but I have not done thorough review and I am not intimately familiar with NRBF details to sign-off. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no more blocking comments. The deserializer code looks good.
@ericstj @carlossanlop one of the CI legs keeps failing with the following error (and it's the last error so it's blocking me from merging this PR):
Is it some kind of a chicken and egg problem? How do I fix it? My current guess is to add sth similar to https://github.com/dotnet/runtime/blob/main/src/libraries/testPackages/packageSettings/System.Windows.Extensions/settings.targets but it's just a guess. FWIW the magic repro command:
|
For brand new packages you need to tell APICompat that a previous version doesn't exist. Do that by adding runtime/src/libraries/System.Net.ServerSentEvents/src/System.Net.ServerSentEvents.csproj Lines 13 to 16 in d2cada8
I'll make a suggestion that fixes it. Also - you can reproduce this by running |
Co-authored-by: Eric StJohn <ericstj@microsoft.com>
@ericstj thanks a lot! |
src/libraries/System.Formats.Nrbf/src/System.Formats.Nrbf.csproj
Outdated
Show resolved
Hide resolved
/ba-g There is only one test failure and it's known, so the Build Anslysis should be green. |
System.Formats.Nrbf isn't a great ".NET like" name, it's not clear what the acronym stands for and it wouldn't be easy to find. Couldn't it just be BinaryFormat, RemotingBinaryFormat or something else that is not a 4 letter acronym? Citing from General Naming Conventions |
The name "Nrbf" comes from the name of the spec: |
Changes:
PayloadReader
toNrbfDecoder
,ArrayRecord<T>
toSZArrayRecord<T>
andRead
toDecode
ClassRecord.TypeName
RecordType
toSerializationRecordType
SerializationRecordType
values that can not be used by the userSerializationRecordType : int
, notSerializationRecordType : byte
fixes #102014
I am going to try to add
ArrayRecord.TotalElementsCount
in a separate PR, as I need to verify how to implement it for jagged arrays and get the name approved