VarInt class, TxIn/TXOut/Tx serializarion, some CKey and CPubKey methods
[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 = Interop.LEBytes((ushort)n);
37                 }
38                 else if (n <= uint.MaxValue)
39                 {
40                     // uint flag
41                     prefix = 0xfe;
42                     valueBytes = Interop.LEBytes((uint)n);
43                 }
44                 else
45                 {
46                     // ulong flag
47                     prefix = 0xff;
48                     valueBytes = Interop.LEBytes(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             byte[] bytesArray = bytes.ToArray();
83
84             if (!BitConverter.IsLittleEndian)
85             {
86                 // Values are stored in little-endian order
87                 Array.Reverse(bytesArray);
88             }
89
90             switch (prefix)
91             {
92                 case 0xfd: // ushort flag
93                     return BitConverter.ToUInt16(bytesArray, 0);
94                 case 0xfe: // uint flag
95                     return BitConverter.ToUInt32(bytesArray, 0);
96                 case 0xff: // ulong flag
97                     return BitConverter.ToUInt64(bytesArray, 0);
98                 default:
99                     return prefix;
100             }
101         }
102     }
103 }