Merge pull request #4 from Arcus92/master
Fixes incomplete stream reads with .NET 6
This commit is contained in:
commit
44e723fb11
|
@ -70,7 +70,7 @@ namespace SharpNBT
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Span<byte> buffer = stackalloc byte[sizeof(short)];
|
Span<byte> buffer = stackalloc byte[sizeof(short)];
|
||||||
BaseStream.Read(buffer);
|
ReadToFixSizedBuffer(buffer);
|
||||||
value = BitConverter.ToInt16(buffer);
|
value = BitConverter.ToInt16(buffer);
|
||||||
if (SwapEndian)
|
if (SwapEndian)
|
||||||
value = value.SwapEndian();
|
value = value.SwapEndian();
|
||||||
|
@ -109,7 +109,7 @@ namespace SharpNBT
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Span<byte> buffer = stackalloc byte[sizeof(long)];
|
Span<byte> buffer = stackalloc byte[sizeof(long)];
|
||||||
BaseStream.Read(buffer);
|
ReadToFixSizedBuffer(buffer);
|
||||||
value = BitConverter.ToInt64(buffer);
|
value = BitConverter.ToInt64(buffer);
|
||||||
if (SwapEndian)
|
if (SwapEndian)
|
||||||
value = value.SwapEndian();
|
value = value.SwapEndian();
|
||||||
|
@ -129,7 +129,7 @@ namespace SharpNBT
|
||||||
var name = named ? ReadUTF8String() : null;
|
var name = named ? ReadUTF8String() : null;
|
||||||
|
|
||||||
var buffer = new byte[sizeof(float)];
|
var buffer = new byte[sizeof(float)];
|
||||||
BaseStream.Read(buffer, 0, sizeof(float));
|
ReadToFixSizedBuffer(buffer, 0, sizeof(float));
|
||||||
if (SwapEndian)
|
if (SwapEndian)
|
||||||
Array.Reverse(buffer);
|
Array.Reverse(buffer);
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ namespace SharpNBT
|
||||||
{
|
{
|
||||||
var name = named ? ReadUTF8String() : null;
|
var name = named ? ReadUTF8String() : null;
|
||||||
var buffer = new byte[sizeof(double)];
|
var buffer = new byte[sizeof(double)];
|
||||||
BaseStream.Read(buffer, 0, buffer.Length);
|
ReadToFixSizedBuffer(buffer, 0, buffer.Length);
|
||||||
if (SwapEndian)
|
if (SwapEndian)
|
||||||
Array.Reverse(buffer);
|
Array.Reverse(buffer);
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ namespace SharpNBT
|
||||||
var name = named ? ReadUTF8String() : null;
|
var name = named ? ReadUTF8String() : null;
|
||||||
var count = ReadCount();
|
var count = ReadCount();
|
||||||
var buffer = new byte[count];
|
var buffer = new byte[count];
|
||||||
BaseStream.Read(buffer, 0, count);
|
ReadToFixSizedBuffer(buffer, 0, count);
|
||||||
return new ByteArrayTag(name, buffer);
|
return new ByteArrayTag(name, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ namespace SharpNBT
|
||||||
}
|
}
|
||||||
|
|
||||||
var buffer = new byte[count * INT_SIZE];
|
var buffer = new byte[count * INT_SIZE];
|
||||||
BaseStream.Read(buffer, 0, count * INT_SIZE);
|
ReadToFixSizedBuffer(buffer, 0, count * INT_SIZE);
|
||||||
|
|
||||||
Span<int> values = MemoryMarshal.Cast<byte, int>(buffer);
|
Span<int> values = MemoryMarshal.Cast<byte, int>(buffer);
|
||||||
if (SwapEndian)
|
if (SwapEndian)
|
||||||
|
@ -236,7 +236,7 @@ namespace SharpNBT
|
||||||
}
|
}
|
||||||
|
|
||||||
var buffer = new byte[count * LONG_SIZE];
|
var buffer = new byte[count * LONG_SIZE];
|
||||||
BaseStream.Read(buffer, 0, count * LONG_SIZE);
|
ReadToFixSizedBuffer(buffer, 0, count * LONG_SIZE);
|
||||||
|
|
||||||
Span<long> values = MemoryMarshal.Cast<byte, long>(buffer);
|
Span<long> values = MemoryMarshal.Cast<byte, long>(buffer);
|
||||||
if (SwapEndian)
|
if (SwapEndian)
|
||||||
|
@ -397,7 +397,7 @@ namespace SharpNBT
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Span<byte> buffer = stackalloc byte[sizeof(ushort)];
|
Span<byte> buffer = stackalloc byte[sizeof(ushort)];
|
||||||
BaseStream.Read(buffer);
|
ReadToFixSizedBuffer(buffer);
|
||||||
var uint16 = BitConverter.ToUInt16(buffer);
|
var uint16 = BitConverter.ToUInt16(buffer);
|
||||||
length = SwapEndian ? uint16.SwapEndian() : uint16;
|
length = SwapEndian ? uint16.SwapEndian() : uint16;
|
||||||
}
|
}
|
||||||
|
@ -406,7 +406,7 @@ namespace SharpNBT
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var utf8 = new byte[length];
|
var utf8 = new byte[length];
|
||||||
BaseStream.Read(utf8, 0, length);
|
ReadToFixSizedBuffer(utf8, 0, length);
|
||||||
return Encoding.UTF8.GetString(utf8);
|
return Encoding.UTF8.GetString(utf8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,11 +419,53 @@ namespace SharpNBT
|
||||||
private int ReadInt32()
|
private int ReadInt32()
|
||||||
{
|
{
|
||||||
Span<byte> buffer = stackalloc byte[sizeof(int)];
|
Span<byte> buffer = stackalloc byte[sizeof(int)];
|
||||||
BaseStream.Read(buffer);
|
ReadToFixSizedBuffer(buffer);
|
||||||
var value = BitConverter.ToInt32(buffer);
|
var value = BitConverter.ToInt32(buffer);
|
||||||
return SwapEndian ? value.SwapEndian() : value;
|
return SwapEndian ? value.SwapEndian() : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads bytes from the streams and stores them into the <paramref name="buffer"/>.
|
||||||
|
/// The number of read bytes is dictated by the size of the buffer.
|
||||||
|
/// This method ensures that all requested bytes are read.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Use this instead of <c>BaseStream.Read(buffer)</c>.
|
||||||
|
/// There was a breaking change in .NET 6 where the <see cref="Stream.Read(byte[],int,int)"/> can read less bytes than requested for certain streams.
|
||||||
|
/// Read more here: https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/partial-byte-reads-in-streams
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="buffer">The buffer where the read bytes are written to. the buffer size defines the number of bytes to read.</param>
|
||||||
|
/// <exception cref="EndOfStreamException">Throws if no more bytes could be read from the stream, but the buffer wasn't completely filled yet.</exception>
|
||||||
|
protected void ReadToFixSizedBuffer(Span<byte> buffer)
|
||||||
|
{
|
||||||
|
var totalBytes = 0;
|
||||||
|
while (totalBytes < buffer.Length)
|
||||||
|
{
|
||||||
|
var readBytes = BaseStream.Read(buffer.Slice(totalBytes));
|
||||||
|
if (readBytes == 0)
|
||||||
|
throw new EndOfStreamException();
|
||||||
|
totalBytes += readBytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads bytes from the streams and stores them into the <paramref name="buffer"/>.
|
||||||
|
/// This method ensures that all requested bytes are read.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Use this instead of <c>BaseStream.Read(buffer, offset, count)</c>.
|
||||||
|
/// There was a breaking change in .NET 6 where the <see cref="Stream.Read(byte[],int,int)"/> can read less bytes than requested for certain streams.
|
||||||
|
/// Read more here: https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/partial-byte-reads-in-streams
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="buffer">The buffer where the read bytes are written to. The data will be stored starting at <paramref name="offset"/> to <paramref name="offset"/> + <paramref name="count"/> - 1.</param>
|
||||||
|
/// <param name="offset">The offset in <paramref name="buffer"/> where the read data is stored.</param>
|
||||||
|
/// <param name="count">The number of bytes to read. Must be positive.</param>
|
||||||
|
/// <exception cref="EndOfStreamException">Throws if no more bytes could be read from the stream, but the buffer wasn't completely filled yet.</exception>
|
||||||
|
protected void ReadToFixSizedBuffer(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
ReadToFixSizedBuffer(new Span<byte>(buffer, offset, count));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -465,6 +507,5 @@ namespace SharpNBT
|
||||||
TagEncountered.Invoke(this, args);
|
TagEncountered.Invoke(this, args);
|
||||||
return args.Handled ? args.Result : null;
|
return args.Handled ? args.Result : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue