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.
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.
| [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.
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.
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.
PTAL at daa7431, I think I was able to remove the need for having this separate stack
There was a problem hiding this comment.
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.
See my comment about bitwise-equality: https://github.com/dotnet/runtime/pull/103232/files/a171648cfff83059d12b0021fc162bea9d67de5b#r1635270940
There was a problem hiding this comment.
@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.
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.
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.
@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.
The issue that I have linked in my comment has the design discussion about it.
There was a problem hiding this comment.
@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. |
JeremyKuhne
left a comment
There was a problem hiding this comment.
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 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:
PayloadReadertoNrbfDecoder,ArrayRecord<T>toSZArrayRecord<T>andReadtoDecodeClassRecord.TypeNameRecordTypetoSerializationRecordTypeSerializationRecordTypevalues that can not be used by the userSerializationRecordType : int, notSerializationRecordType : bytefixes #102014
I am going to try to add
ArrayRecord.TotalElementsCountin a separate PR, as I need to verify how to implement it for jagged arrays and get the name approved