1
1
using System ;
2
+ using System . Buffers . Binary ;
2
3
using System . Collections . Generic ;
3
4
using System . Runtime . CompilerServices ;
4
5
using MongoDB . Bson . IO ;
@@ -73,7 +74,8 @@ private static T[] ReadBsonArray<T>(
73
74
using var buffer = ThreadStaticBuffer . RentBuffer ( array . Length ) ;
74
75
75
76
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 ( ) ;
77
79
78
80
var result = new List < T > ( ) ;
79
81
@@ -82,10 +84,10 @@ private static T[] ReadBsonArray<T>(
82
84
83
85
while ( index < maxIndex )
84
86
{
85
- ValidateBsonType ( bsonDataType ) ;
87
+ ValidateBsonType ( bsonDataType , span ) ;
86
88
87
89
// Skip name
88
- while ( bytes [ index ] != 0 ) { index ++ ; } ;
90
+ while ( span [ index ] != 0 ) { index ++ ; }
89
91
index ++ ; // Skip string terminating 0
90
92
91
93
T value = default ;
@@ -95,85 +97,86 @@ private static T[] ReadBsonArray<T>(
95
97
{
96
98
case ConversionType . DoubleToSingle :
97
99
{
98
- var v = ( float ) BitConverter . ToDouble ( bytes , index ) ;
100
+ var v = ( float ) BinaryPrimitivesCompat . ReadDoubleLittleEndian ( span . Slice ( index ) ) ;
99
101
100
102
value = Unsafe . As < float , T > ( ref v ) ;
101
103
break ;
102
104
}
103
105
case ConversionType . DoubleToDouble :
104
106
{
105
- var v = BitConverter . ToDouble ( bytes , index ) ;
107
+ var v = BinaryPrimitivesCompat . ReadDoubleLittleEndian ( span . Slice ( index ) ) ;
108
+
106
109
value = Unsafe . As < double , T > ( ref v ) ;
107
110
break ;
108
111
}
109
112
case ConversionType . Decimal128ToDecimal128 :
110
113
{
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 ) ) ;
113
116
var v = Decimal128 . ToDecimal ( Decimal128 . FromIEEEBits ( highBits , lowBits ) ) ;
114
117
115
118
value = Unsafe . As < decimal , T > ( ref v ) ;
116
119
break ;
117
120
}
118
121
case ConversionType . BoolToBool :
119
122
{
120
- var v = bytes [ index ] != 0 ;
123
+ var v = span [ index ] != 0 ;
121
124
122
125
value = Unsafe . As < bool , T > ( ref v ) ;
123
126
break ;
124
127
}
125
128
case ConversionType . Int32ToInt8 :
126
129
{
127
- var v = ( sbyte ) BitConverter . ToInt32 ( bytes , index ) ;
130
+ var v = ( sbyte ) BinaryPrimitives . ReadInt32LittleEndian ( span . Slice ( index ) ) ;
128
131
value = Unsafe . As < sbyte , T > ( ref v ) ;
129
132
130
133
break ;
131
134
}
132
135
case ConversionType . Int32ToUInt8 :
133
136
{
134
- var v = ( byte ) BitConverter . ToInt32 ( bytes , index ) ;
137
+ var v = ( byte ) BinaryPrimitives . ReadInt32LittleEndian ( span . Slice ( index ) ) ;
135
138
value = Unsafe . As < byte , T > ( ref v ) ;
136
139
break ;
137
140
}
138
141
case ConversionType . Int32ToInt16 :
139
142
{
140
- var v = ( short ) BitConverter . ToInt32 ( bytes , index ) ;
143
+ var v = ( short ) BinaryPrimitives . ReadInt32LittleEndian ( span . Slice ( index ) ) ;
141
144
value = Unsafe . As < short , T > ( ref v ) ;
142
145
break ;
143
146
}
144
147
case ConversionType . Int32ToUInt16 :
145
148
{
146
- var v = ( ushort ) BitConverter . ToInt32 ( bytes , index ) ;
149
+ var v = ( ushort ) BinaryPrimitives . ReadInt32LittleEndian ( span . Slice ( index ) ) ;
147
150
value = Unsafe . As < ushort , T > ( ref v ) ;
148
151
break ;
149
152
}
150
153
case ConversionType . Int32ToChar :
151
154
{
152
- var v = BitConverter . ToChar ( bytes , index ) ;
155
+ var v = ( char ) ( ushort ) BinaryPrimitives . ReadInt32LittleEndian ( span . Slice ( index ) ) ;
153
156
value = Unsafe . As < char , T > ( ref v ) ;
154
157
break ;
155
158
}
156
159
case ConversionType . Int32ToInt32 :
157
160
{
158
- var v = BitConverter . ToInt32 ( bytes , index ) ;
161
+ var v = BinaryPrimitives . ReadInt32LittleEndian ( span . Slice ( index ) ) ;
159
162
value = Unsafe . As < int , T > ( ref v ) ;
160
163
break ;
161
164
}
162
165
case ConversionType . Int32ToUInt32 :
163
166
{
164
- var v = BitConverter . ToUInt32 ( bytes , index ) ;
167
+ var v = BinaryPrimitives . ReadUInt32LittleEndian ( span . Slice ( index ) ) ;
165
168
value = Unsafe . As < uint , T > ( ref v ) ;
166
169
break ;
167
170
}
168
171
case ConversionType . Int64ToInt64 :
169
172
{
170
- var v = BitConverter . ToInt64 ( bytes , index ) ;
173
+ var v = BinaryPrimitives . ReadInt64LittleEndian ( span . Slice ( index ) ) ;
171
174
value = Unsafe . As < long , T > ( ref v ) ;
172
175
break ;
173
176
}
174
177
case ConversionType . Int64ToUInt64 :
175
178
{
176
- var v = BitConverter . ToUInt64 ( bytes , index ) ;
179
+ var v = BinaryPrimitives . ReadUInt64LittleEndian ( span . Slice ( index ) ) ;
177
180
value = Unsafe . As < ulong , T > ( ref v ) ;
178
181
break ;
179
182
}
@@ -186,13 +189,13 @@ private static T[] ReadBsonArray<T>(
186
189
index += bsonDataSize ;
187
190
}
188
191
189
- ValidateBsonType ( BsonType . EndOfDocument ) ;
192
+ ValidateBsonType ( BsonType . EndOfDocument , span ) ;
190
193
191
194
return result . ToArray ( ) ;
192
195
193
- void ValidateBsonType ( BsonType bsonType )
196
+ void ValidateBsonType ( BsonType bsonType , Span < byte > span )
194
197
{
195
- if ( ( BsonType ) bytes [ index ] != bsonType )
198
+ if ( ( BsonType ) span [ index ] != bsonType )
196
199
{
197
200
throw new InvalidOperationException ( ) ;
198
201
}
0 commit comments