Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using MongoDB.Bson.IO;
Expand Down Expand Up @@ -73,7 +74,8 @@ private static T[] ReadBsonArray<T>(
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<T>();

Expand All @@ -82,10 +84,10 @@ private static T[] ReadBsonArray<T>(

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;
Expand All @@ -95,85 +97,86 @@ private static T[] ReadBsonArray<T>(
{
case ConversionType.DoubleToSingle:
{
var v = (float)BitConverter.ToDouble(bytes, index);
var v = (float)BinaryPrimitivesCompat.ReadDoubleLittleEndian(span.Slice(index));

value = Unsafe.As<float, T>(ref v);
break;
}
case ConversionType.DoubleToDouble:
{
var v = BitConverter.ToDouble(bytes, index);
var v = BinaryPrimitivesCompat.ReadDoubleLittleEndian(span.Slice(index));

value = Unsafe.As<double, T>(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<decimal, T>(ref v);
break;
}
case ConversionType.BoolToBool:
{
var v = bytes[index] != 0;
var v = span[index] != 0;

value = Unsafe.As<bool, T>(ref v);
break;
}
case ConversionType.Int32ToInt8:
{
var v = (sbyte)BitConverter.ToInt32(bytes, index);
var v = (sbyte)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index));
value = Unsafe.As<sbyte, T>(ref v);

break;
}
case ConversionType.Int32ToUInt8:
{
var v = (byte)BitConverter.ToInt32(bytes, index);
var v = (byte)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index));
value = Unsafe.As<byte, T>(ref v);
break;
}
case ConversionType.Int32ToInt16:
{
var v = (short)BitConverter.ToInt32(bytes, index);
var v = (short)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index));
value = Unsafe.As<short, T>(ref v);
break;
}
case ConversionType.Int32ToUInt16:
{
var v = (ushort)BitConverter.ToInt32(bytes, index);
var v = (ushort)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index));
value = Unsafe.As<ushort, T>(ref v);
break;
}
case ConversionType.Int32ToChar:
{
var v = BitConverter.ToChar(bytes, index);
var v = (char)(ushort)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index));
value = Unsafe.As<char, T>(ref v);
break;
}
case ConversionType.Int32ToInt32:
{
var v = BitConverter.ToInt32(bytes, index);
var v = BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index));
value = Unsafe.As<int, T>(ref v);
break;
}
case ConversionType.Int32ToUInt32:
{
var v = BitConverter.ToUInt32(bytes, index);
var v = BinaryPrimitives.ReadUInt32LittleEndian(span.Slice(index));
value = Unsafe.As<uint, T>(ref v);
break;
}
case ConversionType.Int64ToInt64:
{
var v = BitConverter.ToInt64(bytes, index);
var v = BinaryPrimitives.ReadInt64LittleEndian(span.Slice(index));
value = Unsafe.As<long, T>(ref v);
break;
}
case ConversionType.Int64ToUInt64:
{
var v = BitConverter.ToUInt64(bytes, index);
var v = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(index));
value = Unsafe.As<ulong, T>(ref v);
break;
}
Expand All @@ -186,13 +189,13 @@ private static T[] ReadBsonArray<T>(
index += bsonDataSize;
}

ValidateBsonType(BsonType.EndOfDocument);
ValidateBsonType(BsonType.EndOfDocument, span);

return result.ToArray();

void ValidateBsonType(BsonType bsonType)
void ValidateBsonType(BsonType bsonType, Span<byte> span)
{
if ((BsonType)bytes[index] != bsonType)
if ((BsonType)span[index] != bsonType)
{
throw new InvalidOperationException();
}
Expand Down