Use code contracts.
[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     public class ByteQueue
44     {
45         private int _Index;
46         private List<byte> _Elements;
47
48         public ByteQueue(byte[] List, int Start)
49         {
50             _Elements = new List<byte>(List);
51             _Index = Start;
52         }
53
54         public ByteQueue(byte[] List)
55         {
56             _Elements = new List<byte>(List);
57             _Index = 0;
58         }
59
60         public ByteQueue(List<byte> List, int Start)
61         {
62             _Elements = new List<byte>(List);
63             _Index = Start;
64         }
65
66         public ByteQueue(List<byte> List)
67         {
68             _Elements = new List<byte>(List);
69             _Index = 0;
70         }
71
72         public byte Get()
73         {
74             if (_Elements.Count <= _Index)
75             {
76                 throw new ByteQueueException("No elements left.");
77             }
78
79             return _Elements[_Index++];
80         }
81
82         public byte GetCurrent()
83         {
84             return _Elements[_Index];
85         }
86
87         public byte[] Get(int nCount)
88         {
89             Contract.Requires<ArgumentException>(Count - Index >= nCount, "nCount is greater than amount of elements.");
90
91             var result = _Elements.GetRange(_Index, nCount).ToArray();
92             _Index += nCount;
93
94             return result;
95         }
96
97         public byte[] GetCurrent(int nCount)
98         {
99             Contract.Requires<ArgumentException>(Count - Index >= nCount, "nCount is greater than amount of elements.");
100
101             var result = _Elements.GetRange(_Index, nCount).ToArray();
102
103             return result;
104         }
105
106         /// <summary>
107         /// Current index value
108         /// </summary>
109         public int Index
110         {
111             get { return _Index; }
112         }
113
114         public int Count
115         {
116             get { return _Elements.Count; }
117         }
118
119         public ulong GetVarInt()
120         {
121             byte prefix = Get();
122
123             switch (prefix)
124             {
125                 case 0xfd: // ushort
126                     return BitConverter.ToUInt16(Get(2), 0);
127                 case 0xfe: // uint
128                     return BitConverter.ToUInt32(Get(4), 0);
129                 case 0xff: // ulong
130                     return BitConverter.ToUInt64(Get(8), 0);
131                 default:
132                     return prefix;
133             }
134         }
135     }
136 }