11using System ;
2+ using System . Buffers . Binary ;
23using System . Collections . Generic ;
34using System . Runtime . CompilerServices ;
45using MongoDB . Bson . IO ;
@@ -73,7 +74,8 @@ private static T[] ReadBsonArray<T>(
7374 using var buffer = ThreadStaticBuffer . RentBuffer ( array . Length ) ;
7475
7576 var bytes = buffer . Bytes ;
76- array . GetBytes ( 0 , bytes , 0 , array . Length ) ;
77+ array . GetBytes ( 0 , bytes , 0 , array . Length ) ;
78+ var span = bytes . AsSpan ( ) ;
7779
7880 var result = new List < T > ( ) ;
7981
@@ -82,10 +84,10 @@ private static T[] ReadBsonArray<T>(
8284
8385 while ( index < maxIndex )
8486 {
85- ValidateBsonType ( bsonDataType ) ;
87+ ValidateBsonType ( bsonDataType , span ) ;
8688
8789 // Skip name
88- while ( bytes [ index ] != 0 ) { index ++ ; } ;
90+ while ( span [ index ] != 0 ) { index ++ ; }
8991 index ++ ; // Skip string terminating 0
9092
9193 T value = default ;
@@ -95,85 +97,86 @@ private static T[] ReadBsonArray<T>(
9597 {
9698 case ConversionType . DoubleToSingle :
9799 {
98- var v = ( float ) BitConverter . ToDouble ( bytes , index ) ;
100+ var v = ( float ) BinaryPrimitivesCompat . ReadDoubleLittleEndian ( span . Slice ( index ) ) ;
99101
100102 value = Unsafe . As < float , T > ( ref v ) ;
101103 break ;
102104 }
103105 case ConversionType . DoubleToDouble :
104106 {
105- var v = BitConverter . ToDouble ( bytes , index ) ;
107+ var v = BinaryPrimitivesCompat . ReadDoubleLittleEndian ( span . Slice ( index ) ) ;
108+
106109 value = Unsafe . As < double , T > ( ref v ) ;
107110 break ;
108111 }
109112 case ConversionType . Decimal128ToDecimal128 :
110113 {
111- var lowBits = ( ulong ) BitConverter . ToInt64 ( bytes , index ) ;
112- var highBits = ( ulong ) BitConverter . ToInt64 ( bytes , index + 8 ) ;
114+ var lowBits = BinaryPrimitives . ReadUInt64LittleEndian ( span . Slice ( index ) ) ;
115+ var highBits = BinaryPrimitives . ReadUInt64LittleEndian ( span . Slice ( index + 8 ) ) ;
113116 var v = Decimal128 . ToDecimal ( Decimal128 . FromIEEEBits ( highBits , lowBits ) ) ;
114117
115118 value = Unsafe . As < decimal , T > ( ref v ) ;
116119 break ;
117120 }
118121 case ConversionType . BoolToBool :
119122 {
120- var v = bytes [ index ] != 0 ;
123+ var v = span [ index ] != 0 ;
121124
122125 value = Unsafe . As < bool , T > ( ref v ) ;
123126 break ;
124127 }
125128 case ConversionType . Int32ToInt8 :
126129 {
127- var v = ( sbyte ) BitConverter . ToInt32 ( bytes , index ) ;
130+ var v = ( sbyte ) BinaryPrimitives . ReadInt32LittleEndian ( span . Slice ( index ) ) ;
128131 value = Unsafe . As < sbyte , T > ( ref v ) ;
129132
130133 break ;
131134 }
132135 case ConversionType . Int32ToUInt8 :
133136 {
134- var v = ( byte ) BitConverter . ToInt32 ( bytes , index ) ;
137+ var v = ( byte ) BinaryPrimitives . ReadInt32LittleEndian ( span . Slice ( index ) ) ;
135138 value = Unsafe . As < byte , T > ( ref v ) ;
136139 break ;
137140 }
138141 case ConversionType . Int32ToInt16 :
139142 {
140- var v = ( short ) BitConverter . ToInt32 ( bytes , index ) ;
143+ var v = ( short ) BinaryPrimitives . ReadInt32LittleEndian ( span . Slice ( index ) ) ;
141144 value = Unsafe . As < short , T > ( ref v ) ;
142145 break ;
143146 }
144147 case ConversionType . Int32ToUInt16 :
145148 {
146- var v = ( ushort ) BitConverter . ToInt32 ( bytes , index ) ;
149+ var v = ( ushort ) BinaryPrimitives . ReadInt32LittleEndian ( span . Slice ( index ) ) ;
147150 value = Unsafe . As < ushort , T > ( ref v ) ;
148151 break ;
149152 }
150153 case ConversionType . Int32ToChar :
151154 {
152- var v = BitConverter . ToChar ( bytes , index ) ;
155+ var v = ( char ) ( ushort ) BinaryPrimitives . ReadInt32LittleEndian ( span . Slice ( index ) ) ;
153156 value = Unsafe . As < char , T > ( ref v ) ;
154157 break ;
155158 }
156159 case ConversionType . Int32ToInt32 :
157160 {
158- var v = BitConverter . ToInt32 ( bytes , index ) ;
161+ var v = BinaryPrimitives . ReadInt32LittleEndian ( span . Slice ( index ) ) ;
159162 value = Unsafe . As < int , T > ( ref v ) ;
160163 break ;
161164 }
162165 case ConversionType . Int32ToUInt32 :
163166 {
164- var v = BitConverter . ToUInt32 ( bytes , index ) ;
167+ var v = BinaryPrimitives . ReadUInt32LittleEndian ( span . Slice ( index ) ) ;
165168 value = Unsafe . As < uint , T > ( ref v ) ;
166169 break ;
167170 }
168171 case ConversionType . Int64ToInt64 :
169172 {
170- var v = BitConverter . ToInt64 ( bytes , index ) ;
173+ var v = BinaryPrimitives . ReadInt64LittleEndian ( span . Slice ( index ) ) ;
171174 value = Unsafe . As < long , T > ( ref v ) ;
172175 break ;
173176 }
174177 case ConversionType . Int64ToUInt64 :
175178 {
176- var v = BitConverter . ToUInt64 ( bytes , index ) ;
179+ var v = BinaryPrimitives . ReadUInt64LittleEndian ( span . Slice ( index ) ) ;
177180 value = Unsafe . As < ulong , T > ( ref v ) ;
178181 break ;
179182 }
@@ -186,13 +189,13 @@ private static T[] ReadBsonArray<T>(
186189 index += bsonDataSize ;
187190 }
188191
189- ValidateBsonType ( BsonType . EndOfDocument ) ;
192+ ValidateBsonType ( BsonType . EndOfDocument , span ) ;
190193
191194 return result . ToArray ( ) ;
192195
193- void ValidateBsonType ( BsonType bsonType )
196+ void ValidateBsonType ( BsonType bsonType , Span < byte > span )
194197 {
195- if ( ( BsonType ) bytes [ index ] != bsonType )
198+ if ( ( BsonType ) span [ index ] != bsonType )
196199 {
197200 throw new InvalidOperationException ( ) ;
198201 }
0 commit comments