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);
}
}
}
}
+
+