diff --git a/src/MongoDB.Bson/Serialization/Serializers/PrimitivesArrayReader.cs b/src/MongoDB.Bson/Serialization/Serializers/PrimitivesArrayReader.cs index e811edef230..c8b9bd27cd7 100644 --- a/src/MongoDB.Bson/Serialization/Serializers/PrimitivesArrayReader.cs +++ b/src/MongoDB.Bson/Serialization/Serializers/PrimitivesArrayReader.cs @@ -1,4 +1,5 @@ using System; +using System.Buffers.Binary; using System.Collections.Generic; using System.Runtime.CompilerServices; using MongoDB.Bson.IO; @@ -73,7 +74,8 @@ private static T[] ReadBsonArray( using var buffer = ThreadStaticBuffer.RentBuffer(array.Length); var bytes = buffer.Bytes; - array.GetBytes(0, bytes, 0, array.Length); + array.GetBytes(0, bytes, 0, array.Length); + var span = bytes.AsSpan(); var result = new List(); @@ -82,10 +84,10 @@ private static T[] ReadBsonArray( while (index < maxIndex) { - ValidateBsonType(bsonDataType); + ValidateBsonType(bsonDataType, span); // Skip name - while (bytes[index] != 0) { index++; }; + while (span[index] != 0) { index++; } index++; // Skip string terminating 0 T value = default; @@ -95,21 +97,22 @@ private static T[] ReadBsonArray( { case ConversionType.DoubleToSingle: { - var v = (float)BitConverter.ToDouble(bytes, index); + var v = (float)BinaryPrimitivesCompat.ReadDoubleLittleEndian(span.Slice(index)); value = Unsafe.As(ref v); break; } case ConversionType.DoubleToDouble: { - var v = BitConverter.ToDouble(bytes, index); + var v = BinaryPrimitivesCompat.ReadDoubleLittleEndian(span.Slice(index)); + value = Unsafe.As(ref v); break; } case ConversionType.Decimal128ToDecimal128: { - var lowBits = (ulong)BitConverter.ToInt64(bytes, index); - var highBits = (ulong)BitConverter.ToInt64(bytes, index + 8); + var lowBits = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(index)); + var highBits = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(index + 8)); var v = Decimal128.ToDecimal(Decimal128.FromIEEEBits(highBits, lowBits)); value = Unsafe.As(ref v); @@ -117,63 +120,63 @@ private static T[] ReadBsonArray( } case ConversionType.BoolToBool: { - var v = bytes[index] != 0; + var v = span[index] != 0; value = Unsafe.As(ref v); break; } case ConversionType.Int32ToInt8: { - var v = (sbyte)BitConverter.ToInt32(bytes, index); + var v = (sbyte)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index)); value = Unsafe.As(ref v); break; } case ConversionType.Int32ToUInt8: { - var v = (byte)BitConverter.ToInt32(bytes, index); + var v = (byte)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index)); value = Unsafe.As(ref v); break; } case ConversionType.Int32ToInt16: { - var v = (short)BitConverter.ToInt32(bytes, index); + var v = (short)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index)); value = Unsafe.As(ref v); break; } case ConversionType.Int32ToUInt16: { - var v = (ushort)BitConverter.ToInt32(bytes, index); + var v = (ushort)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index)); value = Unsafe.As(ref v); break; } case ConversionType.Int32ToChar: { - var v = BitConverter.ToChar(bytes, index); + var v = (char)(ushort)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index)); value = Unsafe.As(ref v); break; } case ConversionType.Int32ToInt32: { - var v = BitConverter.ToInt32(bytes, index); + var v = BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index)); value = Unsafe.As(ref v); break; } case ConversionType.Int32ToUInt32: { - var v = BitConverter.ToUInt32(bytes, index); + var v = BinaryPrimitives.ReadUInt32LittleEndian(span.Slice(index)); value = Unsafe.As(ref v); break; } case ConversionType.Int64ToInt64: { - var v = BitConverter.ToInt64(bytes, index); + var v = BinaryPrimitives.ReadInt64LittleEndian(span.Slice(index)); value = Unsafe.As(ref v); break; } case ConversionType.Int64ToUInt64: { - var v = BitConverter.ToUInt64(bytes, index); + var v = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(index)); value = Unsafe.As(ref v); break; } @@ -186,13 +189,13 @@ private static T[] ReadBsonArray( index += bsonDataSize; } - ValidateBsonType(BsonType.EndOfDocument); + ValidateBsonType(BsonType.EndOfDocument, span); return result.ToArray(); - void ValidateBsonType(BsonType bsonType) + void ValidateBsonType(BsonType bsonType, Span span) { - if ((BsonType)bytes[index] != bsonType) + if ((BsonType)span[index] != bsonType) { throw new InvalidOperationException(); }