public class LimitedStream : Stream {
private Stream stream;
private long limit;
public LimitedStream(Stream stream, long limit) {
this.stream = stream;
this.limit = limit;
}
public override bool CanRead { get { return this.stream.CanRead ; } }
public override bool CanSeek { get { return this.stream.CanSeek ; } }
public override bool CanWrite { get { return this.stream.CanWrite; } }
public override long Length { get { return this.stream.Length ; } }
public override long Position {
get { return this.stream.Position; }
set { this.stream.Position = value; }
}
public override void Flush() {
this.stream.Flush();
}
public override int Read(byte[] buffer, int offset, int count) {
Debug.Assert(0 <= Position);
long overlimit = Position + count - (limit + 1); // +1 because we need to read beyond the limit to report an error
if (0 < overlimit) {
if (limit < Position) {
// Not interesting state but we need to check it.
throw new XmlException("Attempt to read beyond the limit ...");
}
Debug.Assert(overlimit < count);
count -= (int)overlimit;
}
int result = this.stream.Read(buffer, offset, count);
if (limit < Position) {
// It may have sence to give more info in the exception, like URI ???
throw new XmlException("Attempt to read beyond the limit ...");
}
return result;
}
public override long Seek(long offset, SeekOrigin origin) {
return this.stream.Seek(offset, origin);
}
public override void SetLength(long value) {
this.stream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count) {
this.stream.Write(buffer, offset, count);
}
}