Mercurial > hg > ucis.core
changeset 8:9525fb2d14ec
Small fix and new functions in PrebufferingStream
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Wed, 16 Jan 2013 23:27:06 +0100 |
parents | 4b78cc5f116b |
children | 9533a87363f3 |
files | Util/PrebufferingStream.cs |
diffstat | 1 files changed, 71 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/Util/PrebufferingStream.cs Sun Jan 13 18:44:17 2013 +0100 +++ b/Util/PrebufferingStream.cs Wed Jan 16 23:27:06 2013 +0100 @@ -7,13 +7,18 @@ namespace UCIS.Util { public class PrebufferingStream : Stream { class AsyncResult : AsyncResultBase { - public int Count { get; private set; } + public Byte[] Buffer { get; set; } + public int Offset { get; set; } public int Left { get; set; } + public int Count { get; set; } public AsyncResult(AsyncCallback callback, Object state) : base(callback, state) { } public void SetCompleted(Boolean synchronously, int count, Exception error) { this.Count = count; base.SetCompleted(synchronously, error); } + public void SetCompleted(Boolean synchronously, Exception error) { + base.SetCompleted(synchronously, error); + } public int WaitForCompletion() { WaitHandle wh = null; lock (this) if (!IsCompleted) wh = AsyncWaitHandle; @@ -43,10 +48,11 @@ } public IAsyncResult BeginPrebuffering(int count, AsyncCallback callback, Object state) { AsyncResult ar = new AsyncResult(callback, state); - if (prebuffercount > count) { - ar.SetCompleted(true, count, null); + if (prebuffercount >= count) { + ar.SetCompleted(true, prebuffercount, null); } else { PrepareBuffer(count); + ar.Left = count - prebuffercount; int off = prebufferoffset + prebuffercount; baseStream.BeginRead(prebuffer, off, prebuffer.Length - off, asyncPrebufferReadCallback, ar); } @@ -153,6 +159,21 @@ } } + public void ReadAll(Byte[] buffer, int offset, int count) { + while (count > 0) { + int read = Read(buffer, offset, count); + if (read <= 0) throw new EndOfStreamException(); + offset += read; + count -= read; + } + } + + public Byte[] ReadAll(int count) { + Byte[] buffer = new Byte[count]; + ReadAll(buffer, 0, count); + return buffer; + } + public override int ReadByte() { if (Prebuffer(1) < 1) return -1; int v = prebuffer[prebufferoffset]; @@ -184,6 +205,53 @@ } } + public IAsyncResult BeginReadAll(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { + AsyncResult ar = new AsyncResult(callback, state); + ar.Buffer = buffer; + ar.Offset = 0; + ar.Left = count; + ar.Count = 0; + if (prebuffercount > 0) { + int read = Math.Min(ar.Left, prebuffercount); + Buffer.BlockCopy(prebuffer, prebufferoffset, ar.Buffer, ar.Offset, read); + prebufferoffset += read; + prebuffercount -= read; + ar.Offset += read; + ar.Left -= read; + ar.Count += read; + } + if (ar.Left > 0) { + baseStream.BeginRead(ar.Buffer, ar.Offset, ar.Left, asyncReadAllReadCallback, ar); + } else { + ar.SetCompleted(true, count, null); + } + return ar; + } + + private void asyncReadAllReadCallback(IAsyncResult ar) { + AsyncResult myar = (AsyncResult)ar.AsyncState; + try { + int len = baseStream.EndRead(ar); + if (len <= 0) throw new EndOfStreamException(); + myar.Offset += len; + myar.Left -= len; + myar.Count += len; + if (myar.Left > 0) { + int off = prebufferoffset + prebuffercount; + baseStream.BeginRead(myar.Buffer, myar.Offset, myar.Left, asyncReadAllReadCallback, ar); + } else { + myar.SetCompleted(false, myar.Count, null); + } + } catch (Exception ex) { + myar.SetCompleted(false, ex); + } + } + + public int EndReadAll(IAsyncResult asyncResult) { + AsyncResult myar = asyncResult as AsyncResult; + return myar.WaitForCompletion(); + } + public override void Close() { base.Close(); baseStream.Close();