Skip to content

Commit

Permalink
Added test coverage for TryReadNew.
Browse files Browse the repository at this point in the history
  • Loading branch information
MeltyPlayer committed Apr 29, 2024
1 parent 310bae7 commit d3a4a22
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 12 deletions.
40 changes: 40 additions & 0 deletions Schema Build Tests/binary/NewTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;

using NUnit.Framework;

using schema.testing;


namespace schema.binary {
public partial class NewTests {
[BinarySchema]
private partial class BinarySchemaThatWillSucceed : IBinaryConvertible {
public int Value { get; set; }
}

[Test]
public void TestTryReadNewSucceeds() {
using var br = SchemaMemoryStream.From([123456]).GetBinaryReader();
Assert.True(
br.TryReadNew<BinarySchemaThatWillSucceed>(out var successful));
Assert.AreEqual(4, br.Position);
Assert.AreEqual(123456, successful.Value);
}

private class BinarySchemaThatWillFail : IBinaryDeserializable {
public void Read(IBinaryReader br) {
br.ReadByte();
throw new Exception();
}
}

[Test]
public void TestTryReadNewFails() {
using var br = SchemaMemoryStream.From([123456]).GetBinaryReader();
Assert.False(
br.TryReadNew<BinarySchemaThatWillFail>(out var successful));
Assert.AreEqual(0, br.Position);
Assert.Null(successful);
}
}
}
45 changes: 45 additions & 0 deletions Schema/src/testing/SchemaMemoryStream.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;
using System.IO;

using CommunityToolkit.HighPerformance;

using schema.binary;
using schema.util.streams;

namespace schema.testing {
public class SchemaMemoryStream(MemoryStream impl)
: ISeekableReadableStream, ISeekableWritableStream {
public static unsafe SchemaMemoryStream From<T>(T[] src)
where T : unmanaged {
var size = sizeof(T);
var data = new byte[size * src.Length];
src.AsSpan().AsBytes().CopyTo(data);

var ms = new MemoryStream(data);
return new SchemaMemoryStream(ms);
}

public IBinaryReader GetBinaryReader()
=> new SchemaBinaryReader(this, this.Endianness);

public void Dispose() => impl.Dispose();

public byte ReadByte() => (byte) impl.ReadByte();
public int Read(Span<byte> dst) => impl.Read(dst);

public long Position {
get => impl.Position;
set => impl.Position = value;
}

public long Length => impl.Length;

public void WriteByte(byte b) => impl.WriteByte(b);
public void Write(ReadOnlySpan<byte> src) => impl.Write(src);

public void Write(IReadableStream readableStream)
=> impl.WriteImpl(readableStream);

public Endianness Endianness => EndiannessUtil.SystemEndianness;
}
}
32 changes: 32 additions & 0 deletions Schema/src/util/streams/BaseStreamImpls.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.IO;
using System.Runtime.CompilerServices;

using CommunityToolkit.HighPerformance;

namespace schema.util.streams {
public static class BasicStreamImpls {
/// <summary>
/// (Straight-up copied from the implementation of Stream.CopyTo())
/// We pick a value that is the largest multiple of 4096 that is still smaller than the large object heap threshold (85K).
/// The CopyTo/CopyToAsync buffer is short-lived and is likely to be collected at Gen0, and it offers a significant
/// improvement in Copy performance.
/// </summary>
private const int DEFAULT_COPY_BUFFER_SIZE = 81920;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void WriteImpl(this Stream impl,
IReadableStream readableStream) {
if (readableStream is ReadableStream readableStreamImpl) {
readableStreamImpl.Impl.CopyTo(impl);
return;
}

Span<byte> buffer = stackalloc byte[DEFAULT_COPY_BUFFER_SIZE];
int bytesRead;
while ((bytesRead = readableStream.Read(buffer)) != 0) {
impl.Write(buffer.Slice(0, bytesRead));
}
}
}
}
14 changes: 2 additions & 12 deletions Schema/src/util/streams/WritableStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,7 @@ public long Length {
public void Write(ReadOnlySpan<byte> src) => impl.Write(src);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(IReadableStream readableStream) {
if (readableStream is ReadableStream readableStreamImpl) {
readableStreamImpl.Impl.CopyTo(impl);
return;
}

Span<byte> buffer = stackalloc byte[DEFAULT_COPY_BUFFER_SIZE];
int bytesRead;
while ((bytesRead = readableStream.Read(buffer)) != 0) {
impl.Write(buffer.Slice(0, bytesRead));
}
}
public void Write(IReadableStream readableStream)
=> impl.WriteImpl(readableStream);
}
}

0 comments on commit d3a4a22

Please sign in to comment.