[API Proposal]: System.Formats.Asn1.AsnValueReader #109019
Labels
api-suggestion
Early API idea and discussion, it is NOT ready for implementation
area-System.Formats.Asn1
Milestone
Background and motivation
Today .NET has two ways to read ASN.1 encoded data.
AsnDecoder
, which is a stateless decoder that can read slices of data and tell you how much is read. It operates onReadOnlySpan<byte>
.AsnReader
which is a "higher abstracted", stateful reader. It operating onReadOnlyMemory<byte>
and works on top ofAsnDecoder
.If you want a stateful decoder that works on
ReadOnlySpan<byte>
, you have to build it yourself on top ofAsnDecoder
.Within .NET Libraries, that is exactly what we have done with the internal
AsnValueReader
.This type is very useful as it makes working with
ReadOnlySpan<byte>
of ASN.1 encoded data easier. Because our own public APIs want to acceptReadOnlySpan<byte>
, we need a way to readReadOnlySpan<byte>
of ASN.1 data. Other library authors are in a similar situation. If they want to exposeReadOnlySpan<byte>
APIs and then interpret it as ASN.1, they are forced to useAsnDecoder
, which is low level, or build their own abstraction.The .NET Libraries in fact vastly prefer to use the internal
AsnValueReader
instead of the publicAsnReader
. This to me indicates there is a gap in the public API.I propose then that we expose an
AsnValueReader
. Its API shape is identical toAsnReader
, save for the fact that it accepts and returnsReadOnlySpan<byte>
instead ofReadOnlyMemory<byte>
, does not need aClone
, and it returnsAsnValueReader
for child readers.API Proposal
API Usage
It will be used the same as
AsnReader
.Alternative Designs
I don't feel strongly about the name. We could call it
AsnValueReader
,ValueAsnReader
,AsnRefReader
, etc.If we want to keep the "reader" APIs on
AsnReader
, we could instead introduce static APIs on it that accept a ref struct. Something likeI don't love this because it does not meaningfully improve the situation over
AsnDecoder
, and it would make the sub-readers likeReadSequence
be a little awkward. We have instance methods for a reason, so we should use them.Risks
The largest risk with this is that since it is a mutable struct, the ergonomics of this make it a tad easy to clone it unintentionally. Such example might be forgetting to pass it by
ref
to a method, or the method having an API shape that forces the compiler to make a hidden copy. For example:I think this risk is acceptable.
The text was updated successfully, but these errors were encountered: