9752c0217320ad40a7b001712ee974fd644cb9cf
[NovacoinLibrary.git] / Novacoin / ByteQueue.cs
1 \feff/**
2  *  Novacoin classes library
3  *  Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
4
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU Affero General Public License as
7  *  published by the Free Software Foundation, either version 3 of the
8  *  License, or (at your option) any later version.
9
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU Affero General Public License for more details.
14
15  *  You should have received a copy of the GNU Affero General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 using System;
20 using System.Collections.Generic;
21 using System.Diagnostics.Contracts;
22
23 namespace Novacoin
24 {
25     [Serializable]
26     public class ByteQueueException : Exception
27     {
28         public ByteQueueException()
29         {
30         }
31
32         public ByteQueueException(string message)
33             : base(message)
34         {
35         }
36
37         public ByteQueueException(string message, Exception inner)
38             : base(message, inner)
39         {
40         }
41     }
42
43     /// <summary>
44     /// Stream of bytes.
45     /// 
46     /// TODO: rewrite using MemoryStream
47     /// </summary>
48     public class ByteQueue
49     {
50         private int _Index;
51         private List<byte> _Elements;
52
53         public ByteQueue(byte[] List, int Start)
54         {
55             _Elements = new List<byte>(List);
56             _Index = Start;
57         }
58
59         public ByteQueue(byte[] List)
60         {
61             _Elements = new List<byte>(List);
62             _Index = 0;
63         }
64
65         public ByteQueue(List<byte> List, int Start)
66         {
67             _Elements = new List<byte>(List);
68             _Index = Start;
69         }
70
71         public ByteQueue(List<byte> List)
72         {
73             _Elements = new List<byte>(List);
74             _Index = 0;
75         }
76
77         public byte Get()
78         {
79             if (_Elements.Count <= _Index)
80             {
81                 throw new ByteQueueException("No elements left.");
82             }
83
84             return _Elements[_Index++];
85         }
86
87         public bool TryGet(ref byte Element)
88         {
89             if (_Elements.Count <= _Index)
90             {
91                 return false;
92             }
93
94             Element = _Elements[_Index++];
95
96             return true;
97         }
98
99         public byte GetCurrent()
100         {
101             return _Elements[_Index];
102         }
103
104         public byte[] Get(int nCount)
105         {
106             Contract.Requires<ArgumentException>(Count - Index >= nCount, "nCount is greater than amount of elements.");
107
108             var result = _Elements.GetRange(_Index, nCount).ToArray();
109             _Index += nCount;
110
111             return result;
112         }
113
114         public bool TryGet(int nCount, ref byte[] Elements)
115         {
116             if (Count - Index < nCount)
117             {
118                 return false;
119             }
120
121             Elements = _Elements.GetRange(_Index, nCount).ToArray();
122             _Index += nCount;
123
124             return true;
125         }
126
127         public byte[] GetCurrent(int nCount)
128         {
129             Contract.Requires<ArgumentException>(Count - Index >= nCount, "nCount is greater than amount of elements.");
130
131             var result = _Elements.GetRange(_Index, nCount).ToArray();
132
133             return result;
134         }
135
136         public bool TryGetCurrent(int nCount, ref byte[] Elements)
137         {
138             if (Count - Index < nCount)
139             {
140                 return false;
141             }
142
143             Elements = _Elements.GetRange(_Index, nCount).ToArray();
144
145             return true;
146         }
147
148         /// <summary>
149         /// Current index value
150         /// </summary>
151         public int Index
152         {
153             get { return _Index; }
154         }
155
156         public int Count
157         {
158             get { return _Elements.Count; }
159         }
160
161         public ulong GetVarInt()
162         {
163             byte prefix = Get();
164
165             switch (prefix)
166             {
167                 case 0xfd: // ushort
168                     return BitConverter.ToUInt16(Get(2), 0);
169                 case 0xfe: // uint
170                     return BitConverter.ToUInt32(Get(4), 0);
171                 case 0xff: // ulong
172                     return BitConverter.ToUInt64(Get(8), 0);
173                 default:
174                     return prefix;
175             }
176         }
177     }
178 }