diff --git a/OpenRA.Game/Primitives/MergedStream.cs b/OpenRA.Game/Primitives/MergedStream.cs index af0e7ac7a0..e4dd99d6ed 100644 --- a/OpenRA.Game/Primitives/MergedStream.cs +++ b/OpenRA.Game/Primitives/MergedStream.cs @@ -9,6 +9,7 @@ */ #endregion +using System; using System.IO; namespace OpenRA.Primitives @@ -18,7 +19,7 @@ namespace OpenRA.Primitives public Stream Stream1 { get; set; } public Stream Stream2 { get; set; } - long VirtualLength { get; set; } + long VirtualLength { get; } long position; public MergedStream(Stream stream1, Stream stream2) @@ -61,7 +62,21 @@ namespace OpenRA.Primitives public override void SetLength(long value) { - VirtualLength = value; + throw new NotSupportedException(); + } + + public override int ReadByte() + { + int value; + + if (position >= Stream1.Length) + value = Stream2.ReadByte(); + else + value = Stream1.ReadByte(); + + position++; + + return value; } public override int Read(byte[] buffer, int offset, int count) @@ -83,12 +98,14 @@ namespace OpenRA.Primitives return bytesRead; } + public override void WriteByte(byte value) + { + throw new NotSupportedException(); + } + public override void Write(byte[] buffer, int offset, int count) { - if (position >= Stream1.Length) - Stream2.Write(buffer, offset - (int)Stream1.Length, count); - else - Stream1.Write(buffer, offset, count); + throw new NotSupportedException(); } public override bool CanRead @@ -103,7 +120,7 @@ namespace OpenRA.Primitives public override bool CanWrite { - get { return Stream1.CanWrite && Stream2.CanWrite; } + get { return false; } } public override long Length diff --git a/OpenRA.Game/Primitives/ReadOnlyAdapterStream.cs b/OpenRA.Game/Primitives/ReadOnlyAdapterStream.cs index 8b53435b8a..1001332b0c 100644 --- a/OpenRA.Game/Primitives/ReadOnlyAdapterStream.cs +++ b/OpenRA.Game/Primitives/ReadOnlyAdapterStream.cs @@ -48,9 +48,25 @@ namespace OpenRA.Primitives public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } public sealed override void SetLength(long value) { throw new NotSupportedException(); } + public sealed override void WriteByte(byte value) { throw new NotSupportedException(); } public sealed override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } public sealed override void Flush() { throw new NotSupportedException(); } + public sealed override int ReadByte() + { + if (data.Count > 0) + return data.Dequeue(); + + while (!baseStreamEmpty) + { + baseStreamEmpty = BufferData(baseStream, data); + if (data.Count > 0) + return data.Dequeue(); + } + + return -1; + } + public sealed override int Read(byte[] buffer, int offset, int count) { var copied = 0; @@ -66,7 +82,8 @@ namespace OpenRA.Primitives } /// - /// Reads data into a buffer, which will be used to satisfy calls. + /// Reads data into a buffer, which will be used to satisfy and + /// calls. /// /// The source stream from which bytes should be read. /// The queue where bytes should be enqueued. Do not dequeue from this buffer. diff --git a/OpenRA.Game/Primitives/SegmentStream.cs b/OpenRA.Game/Primitives/SegmentStream.cs index 66080af01a..7b24bdba7b 100644 --- a/OpenRA.Game/Primitives/SegmentStream.cs +++ b/OpenRA.Game/Primitives/SegmentStream.cs @@ -59,8 +59,35 @@ namespace OpenRA.Primitives set { BaseStream.Position = BaseOffset + value; } } - public override int Read(byte[] buffer, int offset, int count) { return BaseStream.Read(buffer, offset, count); } - public override void Write(byte[] buffer, int offset, int count) { BaseStream.Write(buffer, offset, count); } + public override int ReadByte() + { + if (Position < Length) + return BaseStream.ReadByte(); + return -1; + } + + public override int Read(byte[] buffer, int offset, int count) + { + var remaining = Length - Position; + if (remaining <= 0) + return 0; + return BaseStream.Read(buffer, offset, (int)Math.Min(remaining, count)); + } + + public override void WriteByte(byte value) + { + if (Position < Length) + BaseStream.WriteByte(value); + throw new IOException("Attempted to write past the end of the stream."); + } + + public override void Write(byte[] buffer, int offset, int count) + { + if (Position + count >= Length) + throw new IOException("Attempted to write past the end of the stream."); + BaseStream.Write(buffer, offset, count); + } + public override void Flush() { BaseStream.Flush(); } public override long Seek(long offset, SeekOrigin origin) {