Skip to content
Closed
Show file tree
Hide file tree
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
28 changes: 27 additions & 1 deletion src/MongoDB.Bson/IO/BsonBinaryReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,34 @@ public override byte[] ReadBytes()
State = GetNextState();
return _bsonStream.ReadBytes(size);
}
#pragma warning restore 618

/// <summary>
/// Reads BSON binary data from the reader to the buffer at offset and respecting the size.
/// </summary>
/// <param name="bytes">Target buffer</param>
/// <param name="offset">Target offset</param>
/// <returns>Bytes read</returns>
public override int ReadBytes(byte[] bytes, int offset) {
if (Disposed) { ThrowObjectDisposedException(); }
VerifyBsonType("ReadBytes", BsonType.Binary);

int size = ReadSize();

var subType = _bsonStream.ReadBinarySubType();
if (subType != BsonBinarySubType.Binary)
{
var message = string.Format("ReadBytes requires the binary sub type to be Binary, not {0}.", subType);
throw new FormatException(message);
}

State = GetNextState();

_bsonStream.ReadBytes(bytes, offset, size);

return size;
}

#pragma warning restore 618
/// <summary>
/// Reads a BSON DateTime from the reader.
/// </summary>
Expand Down
22 changes: 22 additions & 0 deletions src/MongoDB.Bson/IO/BsonBinaryWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,28 @@ public override void WriteBytes(byte[] bytes)
State = GetNextState();
}

/// <summary>
/// Writes BSON binary data to the writer.
/// </summary>
/// <param name="bytes">The bytes.</param>
/// <param name="size"> The count of bytes used in the bytes[] </param>
public override void WriteBytes(byte[] bytes, int size)
{
if (Disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
if (State != BsonWriterState.Value)
{
ThrowInvalidState("WriteBytes", BsonWriterState.Value);
}

_bsonStream.WriteBsonType(BsonType.Binary);
WriteNameHelper();
_bsonStream.WriteInt32(size);
_bsonStream.WriteBinarySubType(BsonBinarySubType.Binary);
_bsonStream.WriteBytes(bytes, 0, size);

State = GetNextState();
}

/// <summary>
/// Writes a BSON DateTime to the writer.
/// </summary>
Expand Down
26 changes: 26 additions & 0 deletions src/MongoDB.Bson/IO/BsonDocumentReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,32 @@ public override byte[] ReadBytes()

return binaryData.Bytes;
}

/// <summary>
/// Reads BSON binary data from the reader to the buffer at offset and respecting the size.
/// </summary>
/// <param name="bytes">Target buffer</param>
/// <param name="offset">Target offset</param>
/// <returns>Bytes read</returns>
public override int ReadBytes(byte[] bytes, int offset = 0)
{
if (Disposed) { ThrowObjectDisposedException(); }
VerifyBsonType("ReadBytes", BsonType.Binary);

State = GetNextState();
var binaryData = _currentValue.AsBsonBinaryData;

var subType = binaryData.SubType;
if (subType != BsonBinarySubType.Binary && subType != BsonBinarySubType.OldBinary)
{
var message = string.Format("ReadBytes requires the binary sub type to be Binary, not {0}.", subType);
throw new FormatException(message);
}

binaryData.Bytes.CopyTo(bytes, offset);

return binaryData.Bytes.Length;
}
#pragma warning restore 618

/// <summary>
Expand Down
15 changes: 15 additions & 0 deletions src/MongoDB.Bson/IO/BsonDocumentWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,21 @@ public override void WriteBytes(byte[] bytes)
State = GetNextState();
}

/// <summary>
/// Writes BSON binary data to the writer.
/// </summary>
/// <param name="bytes">The bytes.</param>
/// <param name="size"> The count of bytes used in the bytes[] </param>
public override void WriteBytes(byte[] bytes, int size) {
if (bytes.Length != size) {
// TODO: Better use a buffer manager here or Provide size in BsonBinaryData
var copy = new byte[size];
Buffer.BlockCopy(bytes, 0, copy, 0, size);
WriteBytes(copy);
} else
WriteBytes(bytes);
}

/// <summary>
/// Writes a BSON DateTime to the writer.
/// </summary>
Expand Down
8 changes: 8 additions & 0 deletions src/MongoDB.Bson/IO/BsonReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,14 @@ public BsonType GetCurrentBsonType()
/// <returns>A byte array.</returns>
public abstract byte[] ReadBytes();

/// <summary>
/// Reads BSON binary data from the reader to the buffer at offset and respecting the size.
/// </summary>
/// <param name="bytes">Target buffer</param>
/// <param name="offset">Target offset</param>
/// <returns>Bytes read</returns>
public abstract int ReadBytes(byte[] bytes, int offset = 0);

/// <summary>
/// Reads a BSON DateTime from the reader.
/// </summary>
Expand Down
7 changes: 7 additions & 0 deletions src/MongoDB.Bson/IO/BsonWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,13 @@ public void PushSettings(Action<BsonWriterSettings> configurator)
/// <param name="bytes">The bytes.</param>
public abstract void WriteBytes(byte[] bytes);

/// <summary>
/// Writes BSON binary data to the writer.
/// </summary>
/// <param name="bytes">The bytes.</param>
/// <param name="size"> </param>
public abstract void WriteBytes(byte[] bytes, int size);

/// <summary>
/// Writes a BSON DateTime to the writer.
/// </summary>
Expand Down
8 changes: 8 additions & 0 deletions src/MongoDB.Bson/IO/IBsonReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ public interface IBsonReader : IDisposable
/// <returns>A byte array.</returns>
byte[] ReadBytes();

/// <summary>
/// Reads BSON binary data from the reader to the buffer at offset and respecting the size.
/// </summary>
/// <param name="buffer">Target buffer</param>
/// <param name="offset">Target offset</param>
/// <returns>Bytes read</returns>
int ReadBytes(byte[] buffer, int offset);

/// <summary>
/// Reads a BSON DateTime from the reader.
/// </summary>
Expand Down
7 changes: 7 additions & 0 deletions src/MongoDB.Bson/IO/IBsonWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ public interface IBsonWriter : IDisposable
/// <param name="bytes">The bytes.</param>
void WriteBytes(byte[] bytes);

/// <summary>
/// Writes BSON binary data to the writer.
/// </summary>
/// <param name="bytes">The bytes.</param>
/// <param name="size"> </param>
void WriteBytes(byte[] bytes, int size);

/// <summary>
/// Writes a BSON DateTime to the writer.
/// </summary>
Expand Down
27 changes: 27 additions & 0 deletions src/MongoDB.Bson/IO/JsonReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,33 @@ public override byte[] ReadBytes()
}

return binaryData.Bytes;

}

/// <summary>
/// Reads BSON binary data from the reader to the buffer at offset and respecting the size.
/// </summary>
/// <param name="bytes">Target buffer</param>
/// <param name="offset">Target offset</param>
/// <returns>Bytes read</returns>
public override int ReadBytes(byte[] bytes, int offset)
{

if (Disposed) { ThrowObjectDisposedException(); }
VerifyBsonType("ReadBinaryData", BsonType.Binary);
State = GetNextState();
var binaryData = _currentValue.AsBsonBinaryData;

var subType = binaryData.SubType;
if (subType != BsonBinarySubType.Binary && subType != BsonBinarySubType.OldBinary)
{
var message = string.Format("ReadBytes requires the binary sub type to be Binary, not {0}.", subType);
throw new FormatException(message);
}

binaryData.Bytes.CopyTo(bytes, offset);

return binaryData.Bytes.Length;
#pragma warning restore
}

Expand Down
3 changes: 3 additions & 0 deletions src/MongoDB.Bson/IO/JsonToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
* limitations under the License.
*/




using System;

namespace MongoDB.Bson.IO
Expand Down
15 changes: 15 additions & 0 deletions src/MongoDB.Bson/IO/JsonWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,21 @@ public override void WriteBytes(byte[] bytes)
WriteBinaryData(new BsonBinaryData(bytes, BsonBinarySubType.Binary));
}

/// <summary>
/// Writes BSON binary data to the writer.
/// </summary>
/// <param name="bytes">The bytes.</param>
/// <param name="size"> The count of bytes used in the bytes[] </param>
public override void WriteBytes(byte[] bytes, int size) {
if (bytes.Length != size) {
// TODO: Better use a buffer manager here or Provide size in BsonBinaryData
var copy = new byte[size];
Buffer.BlockCopy(bytes, 0, copy, 0, size);
WriteBytes(copy);
} else
WriteBytes(bytes);
}

/// <summary>
/// Writes a BSON DateTime to the writer.
/// </summary>
Expand Down
7 changes: 7 additions & 0 deletions src/MongoDB.Bson/IO/WrappingBsonWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,13 @@ public virtual void WriteBytes(byte[] bytes)
_wrapped.WriteBytes(bytes);
}

/// <inheritdoc />
public virtual void WriteBytes(byte[] bytes, int size)
{
ThrowIfDisposed();
_wrapped.WriteBytes(bytes, size);
}

/// <inheritdoc />
public virtual void WriteDateTime(long value)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ public byte[] ReadBytes()
return _parent.ReadBytes();
}

public int ReadBytes(byte[] bytes, int offset = 0)
{
return _parent.ReadBytes(bytes, offset);
}

public long ReadDateTime()
{
return _parent.ReadDateTime();
Expand Down
17 changes: 17 additions & 0 deletions tests/MongoDB.Bson.Tests/IO/JsonReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,23 @@ public void TestObjectIdStrict()
Assert.Equal(json, BsonSerializer.Deserialize<ObjectId>(json).ToJson(jsonSettings));
}

[Fact]
public void TestReadWithReusedBuffer() {
var expectedBytes = new byte[] { 0x01, 0x23 };
var json = "HexData(0, \"123\")";
using (_bsonReader = new JsonReader(json))
{
Assert.Equal(BsonType.Binary, _bsonReader.ReadBsonType());
var bytes = new byte[1024];
int readBytes = _bsonReader.ReadBytes(bytes, 50);
Assert.Equal(2, readBytes);
Assert.True(expectedBytes.SequenceEqual(bytes.Skip(50).Take(2)));
Assert.Equal(BsonReaderState.Initial, _bsonReader.State);
}
var expectedJson = "new BinData(0, \"ASM=\")";
Assert.Equal(expectedJson, BsonSerializer.Deserialize<byte[]>(json).ToJson());
}

[Theory]
[InlineData("{ $regex : \"abc\", $options : \"i\" }", "abc", "i")]
[InlineData("{ $regex : \"abc/\", $options : \"i\" }", "abc/", "i")]
Expand Down
14 changes: 14 additions & 0 deletions tests/MongoDB.Bson.Tests/IO/WrappingBsonWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,20 @@ public void WriteBytes_should_call_wrapped()
mockWrapped.Verify(m => m.WriteBytes(value), Times.Once);
}


[Fact]
public void WriteBytesPars_should_call_wrapped()
{
Mock<IBsonWriter> mockWrapped;
var subject = CreateSubject(out mockWrapped);
const int size = 0;
var value = new byte[0];

subject.WriteBytes(value, size);

mockWrapped.Verify(m => m.WriteBytes(value, size), Times.Once);
}

[Fact]
public void WriteBytes_should_throw_when_disposed()
{
Expand Down