44using System . Buffers ;
55using System . Collections . Generic ;
66using System . Linq ;
7+ using System . Runtime . CompilerServices ;
8+ using System . Runtime . InteropServices ;
9+ using System . Threading ;
710
811namespace System . Memory . Tests
912{
1013 public abstract class ReadOnlySequenceFactory < T >
1114 {
1215 public static ReadOnlySequenceFactory < T > ArrayFactory { get ; } = new ArrayTestSequenceFactory ( ) ;
1316 public static ReadOnlySequenceFactory < T > MemoryFactory { get ; } = new MemoryTestSequenceFactory ( ) ;
17+ public static ReadOnlySequenceFactory < T > MemoryManagerFactory { get ; } = new MemoryManagerTestSequenceFactory ( ) ;
1418 public static ReadOnlySequenceFactory < T > SingleSegmentFactory { get ; } = new SingleSegmentTestSequenceFactory ( ) ;
1519 public static ReadOnlySequenceFactory < T > SegmentPerItemFactory { get ; } = new BytePerSegmentTestSequenceFactory ( ) ;
1620 public static ReadOnlySequenceFactory < T > SplitInThree { get ; } = new SegmentsTestSequenceFactory ( 3 ) ;
@@ -37,7 +41,11 @@ internal class MemoryTestSequenceFactory : ReadOnlySequenceFactory<T>
3741 {
3842 public override ReadOnlySequence < T > CreateOfSize ( int size )
3943 {
40- return CreateWithContent ( new T [ size ] ) ;
44+ #if DEBUG
45+ return new ReadOnlySequence < T > ( new ReadOnlyMemory < T > ( new T [ size + 1 ] ) . Slice ( 1 ) ) ;
46+ #else
47+ return new ReadOnlySequence < T > ( new ReadOnlyMemory < T > ( new T [ size ] ) ) ;
48+ #endif
4149 }
4250
4351 public override ReadOnlySequence < T > CreateWithContent ( T [ ] data )
@@ -112,6 +120,49 @@ public override ReadOnlySequence<T> CreateWithContent(T[] data)
112120 }
113121 }
114122
123+ internal class MemoryManagerTestSequenceFactory : ReadOnlySequenceFactory < T >
124+ {
125+ public override ReadOnlySequence < T > CreateOfSize ( int size )
126+ {
127+ #if DEBUG
128+ return new ReadOnlySequence < T > ( new CustomMemoryManager ( size + 1 ) . Memory . Slice ( 1 ) ) ;
129+ #else
130+ return new ReadOnlySequence < T > ( new CustomMemoryManager ( size ) . Memory ) ;
131+ #endif
132+ }
133+
134+ public override ReadOnlySequence < T > CreateWithContent ( T [ ] data )
135+ {
136+ return new ReadOnlySequence < T > ( new CustomMemoryManager ( data ) . Memory ) ;
137+ }
138+
139+ private unsafe class CustomMemoryManager : MemoryManager < T >
140+ {
141+ private readonly T [ ] _buffer ;
142+
143+ public CustomMemoryManager ( int size ) => _buffer = new T [ size ] ;
144+
145+ public CustomMemoryManager ( T [ ] content ) => _buffer = content ;
146+
147+ public unsafe override Span < T > GetSpan ( ) => _buffer ;
148+
149+ public override unsafe MemoryHandle Pin ( int elementIndex = 0 )
150+ {
151+ if ( ( uint ) elementIndex > ( uint ) _buffer . Length )
152+ {
153+ throw new ArgumentOutOfRangeException ( nameof ( elementIndex ) ) ;
154+ }
155+
156+ var handle = GCHandle . Alloc ( _buffer , GCHandleType . Pinned ) ;
157+ return new MemoryHandle ( Unsafe . Add < T > ( ( void * ) handle . AddrOfPinnedObject ( ) , elementIndex ) , handle , this ) ;
158+ }
159+
160+ public override void Unpin ( ) { }
161+
162+ protected override void Dispose ( bool disposing ) { }
163+ }
164+ }
165+
115166 public static ReadOnlySequence < T > CreateSegments ( params T [ ] [ ] inputs ) => CreateSegments ( inputs . Select ( input => ( ReadOnlyMemory < T > ) input . AsMemory ( ) ) ) ;
116167
117168 public static ReadOnlySequence < T > CreateSegments ( IEnumerable < ReadOnlyMemory < T > > inputs )
0 commit comments