1- using System . IO ;
1+ using System ;
2+ using System . IO ;
23using System . Runtime . CompilerServices ;
4+ using System . Runtime . InteropServices ;
35
46namespace Reloaded . Memory . Streams
57{
68 /// <summary>
79 /// An extended version of the <see cref="MemoryStream"/> class that allows you to directly add generic structs to the stream.
810 /// </summary>
9- public partial class ExtendedMemoryStream : MemoryStream
11+ public unsafe partial class ExtendedMemoryStream : MemoryStream
1012 {
13+ private const int MaxStackLimit = 1024 ;
14+
1115 /// <inheritdoc />
1216 public ExtendedMemoryStream ( ) { }
1317
@@ -61,25 +65,78 @@ public void AddPadding(byte value, int alignment = 2048)
6165 /// Appends an unmanaged structure onto the <see cref="MemoryStream"/> and advances the position.
6266 /// </summary>
6367 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
64- public void Write < T > ( T [ ] structure ) where T : unmanaged => Write ( StructArray . GetBytes ( structure ) ) ;
68+ public void Write < T > ( T [ ] structure ) where T : unmanaged
69+ {
70+ for ( int x = 0 ; x < structure . Length ; x ++ )
71+ Write ( ref structure [ x ] ) ;
72+ }
6573
6674 /// <summary>
6775 /// Appends an managed/marshalled structure onto the <see cref="MemoryStream"/> and advances the position.
6876 /// </summary>
6977 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
70- public void Write < T > ( T [ ] structure , bool marshalStructure = true ) => Write ( StructArray . GetBytes ( structure , marshalStructure ) ) ;
78+ public void Write < T > ( T [ ] structure , bool marshalStructure = true )
79+ {
80+ for ( int x = 0 ; x < structure . Length ; x ++ )
81+ Write ( ref structure [ x ] , marshalStructure ) ;
82+ }
7183
7284 /// <summary>
7385 /// Appends an unmanaged structure onto the <see cref="MemoryStream"/> and advances the position.
7486 /// </summary>
7587 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
76- public void Write < T > ( T structure ) where T : unmanaged => Write ( Struct . GetBytes ( structure ) ) ;
88+ public void Write < T > ( T structure ) where T : unmanaged => Write ( ref structure ) ;
89+
90+ /// <summary>
91+ /// Appends an unmanaged structure onto the <see cref="MemoryStream"/> and advances the position.
92+ /// </summary>
93+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
94+ public void Write < T > ( ref T structure ) where T : unmanaged
95+ {
96+ #if FEATURE_NATIVE_SPAN
97+ if ( sizeof ( T ) < MaxStackLimit )
98+ {
99+ Span < byte > stack = stackalloc byte [ sizeof ( T ) ] ;
100+ Struct . GetBytes ( ref structure , stack ) ;
101+ base . Write ( stack ) ;
102+ }
103+ else
104+ {
105+ Write ( Struct . GetBytes ( structure ) ) ;
106+ }
107+ #else
108+ Write ( Struct . GetBytes ( structure ) ) ;
109+ #endif
110+ }
111+
112+ /// <summary>
113+ /// Appends a managed/marshalled structure onto the given <see cref="MemoryStream"/> and advances the position.
114+ /// </summary>
115+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
116+ public void Write < T > ( T structure , bool marshalStructure = true ) => Write ( ref structure , marshalStructure ) ;
77117
78118 /// <summary>
79119 /// Appends a managed/marshalled structure onto the given <see cref="MemoryStream"/> and advances the position.
80120 /// </summary>
81121 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
82- public void Write < T > ( T structure , bool marshalStructure = true ) => Write ( Struct . GetBytes ( structure , marshalStructure ) ) ;
122+ public void Write < T > ( ref T structure , bool marshalStructure = true )
123+ {
124+ #if FEATURE_NATIVE_SPAN
125+ var size = Struct . GetSize < T > ( true ) ;
126+ if ( size < MaxStackLimit )
127+ {
128+ Span < byte > stack = stackalloc byte [ size ] ;
129+ Struct . GetBytes ( ref structure , marshalStructure , stack ) ;
130+ base . Write ( stack ) ;
131+ }
132+ else
133+ {
134+ Write ( Struct . GetBytes ( structure , marshalStructure ) ) ;
135+ }
136+ #else
137+ Write ( Struct . GetBytes ( structure , marshalStructure ) ) ;
138+ #endif
139+ }
83140
84141 /// <summary>
85142 /// Appends bytes onto the given <see cref="MemoryStream"/> and advances the position.
@@ -92,8 +149,8 @@ public void AddPadding(byte value, int alignment = 2048)
92149 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
93150 public void WriteBigEndianPrimitive < T > ( T [ ] structures ) where T : unmanaged
94151 {
95- foreach ( var structure in structures )
96- WriteBigEndianPrimitive ( structure ) ;
152+ for ( var x = 0 ; x < structures . Length ; x ++ )
153+ WriteBigEndianPrimitive ( structures [ x ] ) ;
97154 }
98155
99156 /// <summary>
@@ -102,8 +159,8 @@ public void WriteBigEndianPrimitive<T>(T[] structures) where T : unmanaged
102159 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
103160 public void WriteBigEndianStruct < T > ( T [ ] structures ) where T : unmanaged, IEndianReversible
104161 {
105- foreach ( var structure in structures )
106- WriteBigEndianStruct ( structure ) ;
162+ for ( var x = 0 ; x < structures . Length ; x ++ )
163+ WriteBigEndianStruct ( structures [ x ] ) ;
107164 }
108165
109166 /// <summary>
@@ -113,7 +170,7 @@ public void WriteBigEndianStruct<T>(T[] structures) where T : unmanaged, IEndian
113170 public void WriteBigEndianPrimitive < T > ( T structure ) where T : unmanaged
114171 {
115172 Endian . Reverse ( ref structure ) ;
116- Write ( Struct . GetBytes ( structure ) ) ;
173+ Write ( ref structure ) ;
117174 }
118175
119176 /// <summary>
@@ -123,7 +180,7 @@ public void WriteBigEndianPrimitive<T>(T structure) where T : unmanaged
123180 public void WriteBigEndianStruct < T > ( T structure ) where T : unmanaged, IEndianReversible
124181 {
125182 structure . SwapEndian ( ) ;
126- Write ( Struct . GetBytes ( structure ) ) ;
183+ Write ( ref structure ) ;
127184 }
128185
129186 private static int RoundUp ( int number , int multiple )
0 commit comments