Skip to content

Commit

Permalink
Migrate all parsers to IBinaryReader.
Browse files Browse the repository at this point in the history
  • Loading branch information
GGG-KILLER committed Aug 15, 2022
1 parent 3e42008 commit 7ffa55d
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 81 deletions.
22 changes: 6 additions & 16 deletions Tsu.BinaryParser/src/ByteBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,30 +50,20 @@ public ByteBuffer(byte[] buffer, int size, bool clearWhenReturning)
public void Dispose() => ArrayPool<byte>.Shared.Return(_buffer, _clearWhenReturning);
#endif

public void FillFrom(Stream stream)
{
public void FillFrom(IBinaryReader reader) =>
#if HAS_SPAN
var readBytes = stream.Read(Span);
reader.Read(Span);
#else
var readBytes = stream.Read(_buffer, 0, Length);
reader.Read(_buffer, Length);
#endif

if (readBytes != Length)
throw new EndOfStreamException();
}

public async ValueTask FillFromAsync(Stream stream, CancellationToken cancellationToken = default)
{
public ValueTask FillFromAsync(IBinaryReader reader, CancellationToken cancellationToken = default) =>
#if HAS_SPAN
var readBytes = await stream.ReadAsync(_memoryOwner.Memory.Slice(0, Length), cancellationToken);
reader.ReadAsync(_memoryOwner.Memory.Slice(0, Length), cancellationToken);
#else
var readBytes = await stream.ReadAsync(_buffer, 0, Length, cancellationToken);
reader.ReadAsync(_buffer, Length, cancellationToken);
#endif

if (readBytes != Length)
throw new EndOfStreamException();
}

public void WriteTo(Stream stream) =>
#if HAS_SPAN
stream.Write(Span);
Expand Down
4 changes: 2 additions & 2 deletions Tsu.BinaryParser/src/Parsers/ChangeEndianessParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ public ChangeEndianessParser(Endianess endianess)
public long CalculateSize(Unit value) => 0;

/// <inheritdoc/>
public Unit Deserialize(Stream stream, IBinaryParsingContext context)
public Unit Deserialize(IBinaryReader reader, IBinaryParsingContext context)
{
context.Endianess = _endianess;
return Unit.Value;
}

/// <inheritdoc/>
public ValueTask<Unit> DeserializeAsync(Stream stream, IBinaryParsingContext context, CancellationToken cancellationToken = default)
public ValueTask<Unit> DeserializeAsync(IBinaryReader reader, IBinaryParsingContext context, CancellationToken cancellationToken = default)
{
context.Endianess = _endianess;
return new ValueTask<Unit>(Unit.Value);
Expand Down
13 changes: 5 additions & 8 deletions Tsu.BinaryParser/src/Parsers/FromBytesBinaryParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,16 @@ protected FromBytesBinaryParser(int size, bool clearBuffers)
protected abstract void WriteToBytes(Endianess endianess, Span<byte> buffer, T value);

/// <inheritdoc/>
public T Deserialize(Stream stream, IBinaryParsingContext context)
public T Deserialize(IBinaryReader reader, IBinaryParsingContext context)
{
const int requiredBytes = sizeof(short);

#if HAS_SPAN
Span<byte> bytes = stackalloc byte[requiredBytes];
var readBytes = stream.Read(bytes);

if (readBytes != requiredBytes)
throw new EndOfStreamException();
reader.Read(bytes);
#else
using var buffer = ByteBufferPool.Rent(requiredBytes, _clearBuffers);
buffer.FillFrom(stream);
buffer.FillFrom(reader);
var bytes = buffer.Span;
#endif

Expand All @@ -92,12 +89,12 @@ public T Deserialize(Stream stream, IBinaryParsingContext context)

/// <inheritdoc/>
public async ValueTask<T> DeserializeAsync(
Stream stream,
IBinaryReader reader,
IBinaryParsingContext context,
CancellationToken cancellationToken = default)
{
using var buffer = ByteBufferPool.Rent(sizeof(short), _clearBuffers);
await buffer.FillFromAsync(stream, cancellationToken);
await buffer.FillFromAsync(reader, cancellationToken);
return ReadFromBytes(context.Endianess, buffer.Span);
}

Expand Down
8 changes: 4 additions & 4 deletions Tsu.BinaryParser/src/Parsers/IBinaryParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,17 @@ public interface IBinaryParser<T>
/// <summary>
/// Deserializes the provided object from the stream.
/// </summary>
/// <param name="stream">The stream to read the object from.</param>
/// <param name="reader">The reader to read the object from.</param>
/// <param name="context">The current context for the deserializing process.</param>
/// <returns>The parsed type.</returns>
T Deserialize(Stream stream, IBinaryParsingContext context);
T Deserialize(IBinaryReader reader, IBinaryParsingContext context);

/// <summary>
/// Deserializes the provided object from the stream.
/// </summary>
/// <param name="stream">The stream to read the object from.</param>
/// <param name="reader">The reader to read the object from.</param>
/// <param name="context">The current context for the deserializing process.</param>
/// <param name="cancellationToken">Cancellation token to stop the parsing.</param>
/// <returns>The parsed type.</returns>
ValueTask<T> DeserializeAsync(Stream stream, IBinaryParsingContext context, CancellationToken cancellationToken = default);
ValueTask<T> DeserializeAsync(IBinaryReader reader, IBinaryParsingContext context, CancellationToken cancellationToken = default);
}
14 changes: 5 additions & 9 deletions Tsu.BinaryParser/src/Parsers/Int8BinaryParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,17 @@ public sealed class Int8BinaryParser : IBinaryParser<sbyte>
public long CalculateSize(sbyte value) => sizeof(sbyte);

/// <inheritdoc/>
public sbyte Deserialize(Stream stream, IBinaryParsingContext context)
public sbyte Deserialize(IBinaryReader reader, IBinaryParsingContext context)
{
var val = stream.ReadByte();
if (val == -1)
throw new EndOfStreamException();
var val = reader.ReadByte().UnwrapOrElse(() => throw new EndOfStreamException());
return (sbyte) val;
}

/// <inheritdoc/>
public ValueTask<sbyte> DeserializeAsync(Stream stream, IBinaryParsingContext context, CancellationToken cancellationToken = default)
public ValueTask<sbyte> DeserializeAsync(IBinaryReader reader, IBinaryParsingContext context, CancellationToken cancellationToken = default)
{
var val = stream.ReadByte();
if (val == -1)
throw new EndOfStreamException();
return new ValueTask<sbyte>((sbyte)val);
var val = reader.ReadByte().UnwrapOrElse(() => throw new EndOfStreamException());
return new ValueTask<sbyte>((sbyte) val);
}

/// <inheritdoc/>
Expand Down
19 changes: 10 additions & 9 deletions Tsu.BinaryParser/src/Parsers/NullableParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,14 @@ public NullableParser(
public long CalculateSize(T? value) => 1 + (value is null ? 0 : _wrappedParser.CalculateSize(value));

/// <inheritdoc/>
public T? Deserialize(Stream stream, IBinaryParsingContext context)
public T? Deserialize(IBinaryReader reader, IBinaryParsingContext context)
{
var flag = stream.ReadByte();
var flag = reader.ReadByte();
if (flag == _notNullByte)
{
return _wrappedParser.Deserialize(stream, context);
return _wrappedParser.Deserialize(reader, context);
}
else if (flag == _nullByte || (_acceptEofAsNull && flag == -1))
else if (flag.MapOr(_acceptEofAsNull, f => f == _nullByte))
{
return default;
}
Expand All @@ -90,16 +90,17 @@ public NullableParser(
}

/// <inheritdoc/>
public ValueTask<T?> DeserializeAsync(Stream stream, IBinaryParsingContext context, CancellationToken cancellationToken = default)
public ValueTask<T?> DeserializeAsync(IBinaryReader reader, IBinaryParsingContext context, CancellationToken cancellationToken = default)
{
var flag = stream.ReadByte();
var flag = reader.ReadByte();
if (flag == _notNullByte)
{
return _wrappedParser.DeserializeAsync(stream, context, cancellationToken)!;
return _wrappedParser.DeserializeAsync(reader, context, cancellationToken)!;
}
else if (flag == _nullByte || (_acceptEofAsNull && flag == -1))
else if (flag.MapOr(_acceptEofAsNull, f => f == _nullByte))
{
return new ValueTask<T?>(default(T?));
// C# is a bit buggy on this
return new ValueTask<T?>(null!);
}
else
{
Expand Down
33 changes: 22 additions & 11 deletions Tsu.BinaryParser/src/Parsers/OptionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Tsu.BinaryParser.Parsers;
Expand Down Expand Up @@ -66,32 +67,42 @@ public OptionParser(
public long CalculateSize(Option<T> value) => 1 + value.MapOr(0, _wrappedParser.CalculateSize);

/// <inheritdoc/>
public Option<T> Deserialize(Stream stream, IBinaryParsingContext context)
public Option<T> Deserialize(IBinaryReader reader, IBinaryParsingContext context)
{
var flag = stream.ReadByte();
if (flag is not (-1 or 0))
var flag = reader.ReadByte();
if (flag == _someByte)
{
return _wrappedParser.Deserialize(stream, context);
return _wrappedParser.Deserialize(reader, context);
}
else if (flag.MapOr(_acceptEofAsNone, f => f == _noneByte))
{
return Option.None<T>();
}
else
{
throw new FormatException("Read value does not indicate neither a null nor non-null value.");
}
return Option.None<T>();
}

/// <inheritdoc/>
public async ValueTask<Option<T>> DeserializeAsync(Stream stream, IBinaryParsingContext context, CancellationToken cancellationToken = default)
public ValueTask<Option<T>> DeserializeAsync(IBinaryReader reader, IBinaryParsingContext context, CancellationToken cancellationToken = default)
{
var flag = stream.ReadByte();
var flag = reader.ReadByte();
if (flag == _someByte)
{
return await _wrappedParser.DeserializeAsync(stream, context, cancellationToken);
return Core(reader, context, cancellationToken);
}
else if (flag == _noneByte || (flag == -1 && _acceptEofAsNone))
else if (flag.MapOr(_acceptEofAsNone, f => f == _noneByte))
{
return Option.None<T>();
return new ValueTask<Option<T>>(Option.None<T>());
}
else
{
throw new FormatException("First byte does not indicate either Some nor None");
throw new FormatException("Read value does not indicate neither a null nor non-null value.");
}

async ValueTask<Option<T>> Core(IBinaryReader reader, IBinaryParsingContext context, CancellationToken cancellationToken) =>
Option.Some(await _wrappedParser.DeserializeAsync(reader, context, cancellationToken));
}

/// <inheritdoc/>
Expand Down
18 changes: 4 additions & 14 deletions Tsu.BinaryParser/src/Parsers/UInt8BinaryParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,12 @@ public sealed class UInt8BinaryParser : IBinaryParser<byte>
public long CalculateSize(byte value) => sizeof(byte);

/// <inheritdoc/>
public byte Deserialize(Stream stream, IBinaryParsingContext context)
{
var val = stream.ReadByte();
if (val == -1)
throw new EndOfStreamException();
return (byte) val;
}
public byte Deserialize(IBinaryReader reader, IBinaryParsingContext context) =>
reader.ReadByte().UnwrapOrElse(() => throw new EndOfStreamException());

/// <inheritdoc/>
public ValueTask<byte> DeserializeAsync(Stream stream, IBinaryParsingContext context, CancellationToken cancellationToken = default)
{
var val = stream.ReadByte();
if (val == -1)
throw new EndOfStreamException();
return new ValueTask<byte>((byte) val);
}
public ValueTask<byte> DeserializeAsync(IBinaryReader reader, IBinaryParsingContext context, CancellationToken cancellationToken = default) =>
new ValueTask<byte>(reader.ReadByte().UnwrapOrElse(() => throw new EndOfStreamException()));

/// <inheritdoc/>
public void Serialize(Stream stream, IBinaryParsingContext context, byte value) =>
Expand Down
8 changes: 4 additions & 4 deletions Tsu.BinaryParser/src/Parsers/WithByteOrderMark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ public WithByteOrderMark(IBinaryParser<T> wrappedParser, T littleEndianValue, T
public long CalculateSize(T value) => _wrappedParser.CalculateSize(value);

/// <inheritdoc/>
public T Deserialize(Stream stream, IBinaryParsingContext context)
public T Deserialize(IBinaryReader reader, IBinaryParsingContext context)
{
var value = _wrappedParser.Deserialize(stream, context);
var value = _wrappedParser.Deserialize(reader, context);
if (_equalityComparer.Equals(value, _littleEndianValue))
{
context.Endianess = Endianess.LittleEndian;
Expand All @@ -96,9 +96,9 @@ public T Deserialize(Stream stream, IBinaryParsingContext context)
}

/// <inheritdoc/>
public async ValueTask<T> DeserializeAsync(Stream stream, IBinaryParsingContext context, CancellationToken cancellationToken = default)
public async ValueTask<T> DeserializeAsync(IBinaryReader reader, IBinaryParsingContext context, CancellationToken cancellationToken = default)
{
var value = await _wrappedParser.DeserializeAsync(stream, context, cancellationToken);
var value = await _wrappedParser.DeserializeAsync(reader, context, cancellationToken);
if (_equalityComparer.Equals(value, _littleEndianValue))
{
context.Endianess = Endianess.LittleEndian;
Expand Down
8 changes: 4 additions & 4 deletions Tsu.BinaryParser/src/Parsers/WithEndianessParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ public WithEndianessParser(IBinaryParser<T> wrappedParser, Endianess endianess)
public long CalculateSize(T value) => _wrappedParser.CalculateSize(value);

/// <inheritdoc/>
public T Deserialize(Stream stream, IBinaryParsingContext context)
public T Deserialize(IBinaryReader reader, IBinaryParsingContext context)
{
var previousEndianess = context.Endianess;
try
{
context.Endianess = _endianess;
return _wrappedParser.Deserialize(stream, context);
return _wrappedParser.Deserialize(reader, context);
}
finally
{
Expand All @@ -71,13 +71,13 @@ public T Deserialize(Stream stream, IBinaryParsingContext context)
}

/// <inheritdoc/>
public async ValueTask<T> DeserializeAsync(Stream stream, IBinaryParsingContext context, CancellationToken cancellationToken = default)
public async ValueTask<T> DeserializeAsync(IBinaryReader reader, IBinaryParsingContext context, CancellationToken cancellationToken = default)
{
var previousEndianess = context.Endianess;
try
{
context.Endianess = _endianess;
return await _wrappedParser.DeserializeAsync(stream, context, cancellationToken);
return await _wrappedParser.DeserializeAsync(reader, context, cancellationToken);
}
finally
{
Expand Down

0 comments on commit 7ffa55d

Please sign in to comment.