Skip to content

Commit

Permalink
throw EndOfStreamException if stream doesn't return enough bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralf committed Oct 29, 2020
1 parent a28fbde commit e31c339
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 5 deletions.
84 changes: 84 additions & 0 deletions src/Hyperion.Tests/IncompleteStreamTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System.IO;
using Xunit;

namespace Hyperion.Tests
{
public class IncompleteStreamTests : TestBase
{
private const int IncompleteBytes = 4;

public IncompleteStreamTests()
: base(x => new IncompleteReadStream(x, IncompleteBytes))
{
}

[Fact]
public void ThrowsOnEOF()
{
double data = 4; //double has 8 bytes
Serialize(data);
Reset();

// manifest requires 1 byte
// incomplete returned bytes are then (IncompleteBytes)4 - 1 = 3 => EOF
Assert.Throws<EndOfStreamException>(() => Deserialize<int>());
}

private class IncompleteReadStream : Stream
{
private readonly Stream _baseStream;
private readonly int _maxReadBytes;

private int _totalReadBytes;

public IncompleteReadStream(Stream baseStream, int maxReadBytes)
{
_baseStream = baseStream;
_maxReadBytes = maxReadBytes;
}

public override void Flush()
{
_baseStream.Flush();
}

public override long Seek(long offset, SeekOrigin origin)
{
return _baseStream.Seek(offset, origin);
}

public override void SetLength(long value)
{
_baseStream.SetLength(value);
}

public override int Read(byte[] buffer, int offset, int count)
{
var allBytes = _totalReadBytes + count;
var bytesToRead = allBytes > _maxReadBytes
? _maxReadBytes - _totalReadBytes
: count;

var readBytes = _baseStream.Read(buffer, offset, bytesToRead);
_totalReadBytes += readBytes;
return readBytes;
}

public override void Write(byte[] buffer, int offset, int count)
{
_baseStream.Write(buffer, offset, count);
}

public override bool CanRead => _baseStream.CanRead;
public override bool CanSeek => _baseStream.CanSeek;
public override bool CanWrite => _baseStream.CanWrite;
public override long Length => _baseStream.Length;

public override long Position
{
get => _baseStream.Position;
set => _baseStream.Position = value;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

namespace Hyperion.Tests
{
public class PartialStreamTest : PrimitivesTest
public class PartialStreamTests : PrimitivesTest
{
public PartialStreamTest()
public PartialStreamTests()
: base(x => new OneBytePerReadStream(x))
{
}

private class OneBytePerReadStream : Stream
{
private readonly Stream _baseStream;
Expand Down
8 changes: 6 additions & 2 deletions src/Hyperion/Extensions/StreamEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,8 @@ public static string ReadString(this Stream stream, DeserializerSession session)
}

var buffer = session.GetBuffer(length);

stream.ReadFull(buffer, 0, length);

var res = StringEx.FromUtf8Bytes(buffer, 0, length);
return res;
}
Expand All @@ -213,12 +213,16 @@ public static int ReadFull(this Stream stream, byte[] buffer, int offset, int co
{
var readBytes = stream.Read(buffer, offset + totalReadBytes, count - totalReadBytes);
if (readBytes == 0)
break;
break; // EOF

totalReadBytes += readBytes;
}
while (totalReadBytes < count);

// received enough bytes?
if (totalReadBytes != count)
throw new EndOfStreamException("Stream didn't returned sufficient bytes");

return totalReadBytes;
}
}
Expand Down

0 comments on commit e31c339

Please sign in to comment.