X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=Novacoin%2FByteQueue.cs;h=8af351f1abd265ab2991198285a60db26ab053a3;hb=be9d844557911f95165d2c9875c4f5b2822cfc92;hp=1b32adff7eea7491ec1370df8c2a028c640b70dc;hpb=4426ee1dc8ae6733d46b5413d3bce28333792d22;p=NovacoinLibrary.git diff --git a/Novacoin/ByteQueue.cs b/Novacoin/ByteQueue.cs index 1b32adf..8af351f 100644 --- a/Novacoin/ByteQueue.cs +++ b/Novacoin/ByteQueue.cs @@ -18,10 +18,12 @@ using System; using System.Collections.Generic; -using System.Linq; +using System.Diagnostics.Contracts; +using System.IO; namespace Novacoin { + [Serializable] public class ByteQueueException : Exception { public ByteQueueException() @@ -39,99 +41,141 @@ namespace Novacoin } } - public class ByteQueue + /// + /// Stream of bytes. + /// + /// TODO: rewrite using MemoryStream + /// + public class ByteQueue : IDisposable { - private int Index; - private List Elements; + private bool disposed = false; - public ByteQueue(IList List, int Start) + private MemoryStream _Stream; + private BinaryReader _Reader; + + public ByteQueue(ref byte[] buffer, int Start) { - Elements = new List(List); - Index = Start; + _Stream = new MemoryStream(buffer); + _Stream.Seek(Start, SeekOrigin.Begin); + _Reader = new BinaryReader(_Stream); } - public ByteQueue(IList List) + public ByteQueue(ref byte[] buffer) { - Elements = new List(List); - Index = 0; + _Stream = new MemoryStream(buffer); + _Reader = new BinaryReader(_Stream); } - public byte Get() + public ByteQueue(ref List List, int Start) { - if (Elements.Count <= Index) - { - throw new ByteQueueException("No elements left."); - } + _Stream = new MemoryStream(List.ToArray()); + _Stream.Seek(Start, SeekOrigin.Begin); + _Reader = new BinaryReader(_Stream); + } - return Elements[Index++]; + public ByteQueue(ref List List) + { + _Stream = new MemoryStream(List.ToArray()); + _Reader = new BinaryReader(_Stream); } - public byte GetCurrent() + ~ByteQueue() { - return Elements[Index]; + Dispose(false); } - public byte[] Get(int Count) + public void Dispose() { - if (Elements.Count - Index < Count) + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!disposed) { - throw new ByteQueueException("Unable to read requested amount of data."); + if (disposing) + { + _Reader.Dispose(); + _Stream.Dispose(); + } + + disposed = true; } + } - byte[] result = Elements.Skip(Index).Take(Count).ToArray(); - Index += Count; + public byte Get() + { + if (_Stream.Position == _Stream.Length) + { + throw new ByteQueueException("No elements left."); + } - return result; + return _Reader.ReadByte(); } - public byte[] GetCurrent(int Count) + public bool TryGet(ref byte Element) { - if (Elements.Count - Index < Count) + if (_Stream.Position == _Stream.Length) { - throw new ByteQueueException("Unable to read requested amount of data."); + return false; } - byte[] result = Elements.Skip(Index).Take(Count).ToArray(); + Element = _Reader.ReadByte(); - return result; + return true; + } + + public byte[] Get(int nCount) + { + Contract.Requires(Count - Index >= nCount, "nCount is greater than amount of elements."); + + return _Reader.ReadBytes(nCount); + } + + public bool TryGet(int nCount, ref byte[] Elements) + { + Elements = _Reader.ReadBytes(nCount); + return (Elements.Length == nCount); } /// /// Current index value /// - public int CurrentIndex + public int Index { - get { return Index; } + get { return (int)_Stream.Position; } } - public IEnumerable GetEnumerable(int Count) + public int Count { - if (Elements.Count - Index < Count) - { - throw new ByteQueueException("Unable to read requested amount of data."); - } - - IEnumerable result = Elements.Skip(Index).Take(Count); - Index += Count; - - return result; + get { return (int)_Stream.Length; } } public ulong GetVarInt() { - byte prefix = Get(); - - switch (prefix) + try { - case 0xfd: // ushort - return BitConverter.ToUInt16(Get(2), 0); - case 0xfe: // uint - return BitConverter.ToUInt32(Get(4), 0); - case 0xff: // ulong - return BitConverter.ToUInt64(Get(8), 0); - default: - return prefix; + byte prefix = _Reader.ReadByte(); + + switch (prefix) + { + case 0xfd: // ushort + return _Reader.ReadUInt16(); + case 0xfe: // uint + return _Reader.ReadUInt32(); + case 0xff: // ulong + return _Reader.ReadUInt64(); + default: + return prefix; + } + } + catch (EndOfStreamException e) + { + throw new ByteQueueException("No elements left.", e); } } } } + +