@@ -194,6 +194,15 @@ public static class Reader
194194 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
195195 public static Reader < BufferSliceReaderInput > Create ( BufferSlice input , SerializerSession session ) => new ( new BufferSliceReaderInput ( in input ) , session , 0 ) ;
196196
197+ /// <summary>
198+ /// Creates a reader for the provided buffer.
199+ /// </summary>
200+ /// <param name="input">The input.</param>
201+ /// <param name="session">The session.</param>
202+ /// <returns>A new <see cref="Reader{TInput}"/>.</returns>
203+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
204+ public static Reader < ArcBufferReaderInput > Create ( ArcBuffer input , SerializerSession session ) => new ( new ArcBufferReaderInput ( in input ) , session , 0 ) ;
205+
197206 /// <summary>
198207 /// Creates a reader for the provided input stream.
199208 /// </summary>
@@ -267,6 +276,7 @@ public ref struct Reader<TInput>
267276 private readonly static bool IsReadOnlySequenceInput = typeof ( TInput ) == typeof ( ReadOnlySequenceInput ) ;
268277 private readonly static bool IsReaderInput = typeof ( ReaderInput ) . IsAssignableFrom ( typeof ( TInput ) ) ;
269278 private readonly static bool IsBufferSliceInput = typeof ( TInput ) == typeof ( BufferSliceReaderInput ) ;
279+ private readonly static bool IsArcBufferInput = typeof ( TInput ) == typeof ( ArcBufferReaderInput ) ;
270280
271281 private ReadOnlySpan < byte > _currentSpan ;
272282 private int _bufferPos ;
@@ -297,6 +307,15 @@ internal Reader(TInput input, SerializerSession session, long globalOffset)
297307 _bufferSize = _currentSpan . Length ;
298308 _sequenceOffset = globalOffset ;
299309 }
310+ else if ( IsArcBufferInput )
311+ {
312+ _input = input ;
313+ ref var slice = ref Unsafe . As < TInput , ArcBufferReaderInput > ( ref _input ) ;
314+ _currentSpan = slice . GetNext ( ) ;
315+ _bufferPos = 0 ;
316+ _bufferSize = _currentSpan . Length ;
317+ _sequenceOffset = globalOffset ;
318+ }
300319 else if ( IsReaderInput )
301320 {
302321 _input = input ;
@@ -357,6 +376,11 @@ public long Position
357376 var previousBuffersSize = Unsafe . As < TInput , BufferSliceReaderInput > ( ref _input ) . PreviousBuffersSize ;
358377 return _sequenceOffset + previousBuffersSize + _bufferPos ;
359378 }
379+ else if ( IsArcBufferInput )
380+ {
381+ var previousBuffersSize = Unsafe . As < TInput , ArcBufferReaderInput > ( ref _input ) . PreviousBuffersSize ;
382+ return _sequenceOffset + previousBuffersSize + _bufferPos ;
383+ }
360384 else if ( IsSpanInput )
361385 {
362386 return _sequenceOffset + _bufferPos ;
@@ -388,6 +412,10 @@ public long Length
388412 {
389413 return Unsafe . As < TInput , BufferSliceReaderInput > ( ref _input ) . Length ;
390414 }
415+ else if ( IsArcBufferInput )
416+ {
417+ return Unsafe . As < TInput , ArcBufferReaderInput > ( ref _input ) . Length ;
418+ }
391419 else if ( IsSpanInput )
392420 {
393421 return _currentSpan . Length ;
@@ -441,6 +469,22 @@ public void Skip(long count)
441469 }
442470 }
443471 }
472+ else if ( IsArcBufferInput )
473+ {
474+ var end = Position + count ;
475+ while ( Position < end )
476+ {
477+ var previousBuffersSize = Unsafe . As < TInput , ArcBufferReaderInput > ( ref _input ) . PreviousBuffersSize ;
478+ if ( end - previousBuffersSize <= _bufferSize )
479+ {
480+ _bufferPos = ( int ) ( end - previousBuffersSize ) ;
481+ }
482+ else
483+ {
484+ MoveNext ( ) ;
485+ }
486+ }
487+ }
444488 else if ( IsSpanInput )
445489 {
446490 _bufferPos += ( int ) count ;
@@ -496,6 +540,17 @@ public void ForkFrom(long position, out Reader<TInput> forked)
496540 ThrowInvalidPosition ( position , forked . Position ) ;
497541 }
498542 }
543+ else if ( IsArcBufferInput )
544+ {
545+ ref var input = ref Unsafe . As < TInput , ArcBufferReaderInput > ( ref _input ) ;
546+ var newInput = input . ForkFrom ( checked ( ( int ) position ) ) ;
547+ forked = new Reader < TInput > ( Unsafe . As < ArcBufferReaderInput , TInput > ( ref newInput ) , Session , position ) ;
548+
549+ if ( forked . Position != position )
550+ {
551+ ThrowInvalidPosition ( position , forked . Position ) ;
552+ }
553+ }
499554 else if ( IsSpanInput )
500555 {
501556 forked = new Reader < TInput > ( _currentSpan [ ( int ) position ..] , Session , position ) ;
@@ -541,6 +596,10 @@ public void ResumeFrom(long position)
541596 {
542597 // Nothing is required.
543598 }
599+ else if ( IsArcBufferInput )
600+ {
601+ // Nothing is required.
602+ }
544603 else if ( IsSpanInput )
545604 {
546605 // Nothing is required.
@@ -598,6 +657,14 @@ private void MoveNext()
598657 _bufferPos = 0 ;
599658 _bufferSize = _currentSpan . Length ;
600659 }
660+ else if ( IsArcBufferInput )
661+ {
662+ ref var slice = ref Unsafe . As < TInput , ArcBufferReaderInput > ( ref _input ) ;
663+ slice . PreviousBuffersSize += _bufferSize ;
664+ _currentSpan = slice . GetNext ( ) ;
665+ _bufferPos = 0 ;
666+ _bufferSize = _currentSpan . Length ;
667+ }
601668 else if ( IsSpanInput )
602669 {
603670 ThrowInsufficientData ( ) ;
@@ -615,7 +682,7 @@ private void MoveNext()
615682 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
616683 public byte ReadByte ( )
617684 {
618- if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput )
685+ if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput || IsArcBufferInput )
619686 {
620687 var pos = _bufferPos ;
621688 if ( ( uint ) pos < ( uint ) _currentSpan . Length )
@@ -657,7 +724,7 @@ private static byte ReadByteSlow(ref Reader<TInput> reader)
657724 /// <returns>The <see cref="uint"/> which was read.</returns>
658725 public uint ReadUInt32 ( )
659726 {
660- if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput )
727+ if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput || IsArcBufferInput )
661728 {
662729 const int width = 4 ;
663730 if ( _bufferPos + width > _bufferSize )
@@ -701,7 +768,7 @@ static uint ReadSlower(ref Reader<TInput> r)
701768 /// <returns>The <see cref="ulong"/> which was read.</returns>
702769 public ulong ReadUInt64 ( )
703770 {
704- if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput )
771+ if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput || IsArcBufferInput )
705772 {
706773 const int width = 8 ;
707774 if ( _bufferPos + width > _bufferSize )
@@ -779,7 +846,7 @@ public byte[] ReadBytes(uint count)
779846 }
780847
781848 var bytes = new byte [ count ] ;
782- if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput )
849+ if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput || IsArcBufferInput )
783850 {
784851 var destination = new Span < byte > ( bytes ) ;
785852 ReadBytes ( destination ) ;
@@ -798,7 +865,7 @@ public byte[] ReadBytes(uint count)
798865 /// <param name="destination">The destination.</param>
799866 public void ReadBytes ( scoped Span < byte > destination )
800867 {
801- if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput )
868+ if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput || IsArcBufferInput )
802869 {
803870 if ( _bufferPos + destination . Length <= _bufferSize )
804871 {
@@ -846,7 +913,7 @@ private void ReadBytesMultiSegment(scoped Span<byte> dest)
846913 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
847914 public bool TryReadBytes ( int length , out ReadOnlySpan < byte > bytes )
848915 {
849- if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput )
916+ if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput || IsArcBufferInput )
850917 {
851918 if ( _bufferPos + length <= _bufferSize )
852919 {
@@ -879,7 +946,7 @@ public bool TryReadBytes(int length, out ReadOnlySpan<byte> bytes)
879946 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
880947 public unsafe uint ReadVarUInt32 ( )
881948 {
882- if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput )
949+ if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput || IsArcBufferInput )
883950 {
884951 var pos = _bufferPos ;
885952
@@ -937,7 +1004,7 @@ private uint ReadVarUInt32Slow()
9371004 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
9381005 public ulong ReadVarUInt64 ( )
9391006 {
940- if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput )
1007+ if ( IsReadOnlySequenceInput || IsSpanInput || IsBufferSliceInput || IsArcBufferInput )
9411008 {
9421009 var pos = _bufferPos ;
9431010
0 commit comments