TODO
[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 byte GetCurrent()
88         {
89             return _Elements[_Index];
90         }
91
92         public byte[] Get(int nCount)
93         {
94             Contract.Requires<ArgumentException>(Count - Index >= nCount, "nCount is greater than amount of elements.");
95
96             var result = _Elements.GetRange(_Index, nCount).ToArray();
97             _Index += nCount;
98
99             return result;
100         }
101
102         public byte[] GetCurrent(int nCount)
103         {
104             Contract.Requires<ArgumentException>(Count - Index >= nCount, "nCount is greater than amount of elements.");
105
106             var result = _Elements.GetRange(_Index, nCount).ToArray();
107
108             return result;
109         }
110
111         /// <summary>
112         /// Current index value
113         /// </summary>
114         public int Index
115         {
116             get { return _Index; }
117         }
118
119         public int Count
120         {
121             get { return _Elements.Count; }
122         }
123
124         public ulong GetVarInt()
125         {
126             byte prefix = Get();
127
128             switch (prefix)
129             {
130                 case 0xfd: // ushort
131                     return BitConverter.ToUInt16(Get(2), 0);
132                 case 0xfe: // uint
133                     return BitConverter.ToUInt32(Get(4), 0);
134                 case 0xff: // ulong
135                     return BitConverter.ToUInt64(Get(8), 0);
136                 default:
137                     return prefix;
138             }
139         }
140     }
141 }