ea30a581f6b7ee9791e7a294ceee1085345d1bf1
[NovacoinLibrary.git] / Novacoin / VarInt.cs
1 \feffusing System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace Novacoin
8 {
9     public class VarInt
10     {
11         /// <summary>
12         /// Encodes unsigned integer value into compact representation.
13         /// 
14         /// See https://bitcoin.org/en/developer-reference#compactsize-unsigned-integers for additional information.
15         /// </summary>
16         /// <param name="n">Unsigned integer value</param>
17         /// <returns>Byte sequence</returns>
18         public static IList<byte> EncodeVarInt(ulong n)
19         {
20             List<byte> resultBytes = new List<byte>();
21
22             if (n <= 0xfc)
23             {
24                 // Values up to 0xfc are stored directly without any prefix
25                 resultBytes.Add((byte)n);
26             }
27             else
28             {
29                 byte prefix;
30                 byte[] valueBytes;
31
32                 if (n <= ushort.MaxValue)
33                 {
34                     // ushort flag
35                     prefix = 0xfd;
36                     valueBytes = BitConverter.GetBytes((ushort)n);
37                 }
38                 else if (n <= uint.MaxValue)
39                 {
40                     // uint flag
41                     prefix = 0xfe;
42                     valueBytes = BitConverter.GetBytes((uint)n);
43                 }
44                 else
45                 {
46                     // ulong flag
47                     prefix = 0xff;
48                     valueBytes = BitConverter.GetBytes(n);
49                 }
50
51                 resultBytes.Add(prefix);
52                 resultBytes.AddRange(valueBytes);
53             }
54
55             return resultBytes;
56         }
57
58         /// <summary>
59         /// Encodes integer value into compact representation.
60         /// 
61         /// See https://bitcoin.org/en/developer-reference#compactsize-unsigned-integers for additional information.
62         /// </summary>
63         /// <param name="n">Integer value</param>
64         /// <returns>Byte sequence</returns>
65         public static IList<byte> EncodeVarInt(long n)
66         {
67             return EncodeVarInt((ulong)n);
68         }
69
70         /// <summary>
71         /// Decodes integer value from compact representation
72         /// 
73         /// See https://bitcoin.org/en/developer-reference#compactsize-unsigned-integers for additional information.
74         /// </summary>
75         /// <param name="bytes">Byte sequence</param>
76         /// <returns>Integer value</returns>
77         public static ulong DecodeVarInt(IList<byte> bytes)
78         {
79             byte prefix = bytes[0];
80
81             bytes.RemoveAt(0); // Remove prefix
82
83             byte[] bytesArray = bytes.ToArray();
84
85             switch (prefix)
86             {
87                 case 0xfd: // ushort flag
88                     return BitConverter.ToUInt16(bytesArray, 0);
89                 case 0xfe: // uint flag
90                     return BitConverter.ToUInt32(bytesArray, 0);
91                 case 0xff: // ulong flag
92                     return BitConverter.ToUInt64(bytesArray, 0);
93                 default:
94                     return prefix;
95             }
96         }
97     }
98 }