X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=Novacoin%2FVarInt.cs;h=ba174e90fc156c951d6102e16ef2fbe4bf6a08f2;hb=c4aad1332d39a5bdd66e9e8004932dc99baf44e5;hp=ee6652d86709f42d39aa8c741240d5103087be39;hpb=c5c813f88fd93f2360d503f7165cdbcc97189459;p=NovacoinLibrary.git diff --git a/Novacoin/VarInt.cs b/Novacoin/VarInt.cs index ee6652d..ba174e9 100644 --- a/Novacoin/VarInt.cs +++ b/Novacoin/VarInt.cs @@ -1,8 +1,24 @@ -using System; +/** + * Novacoin classes library + * Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com) + + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.IO; namespace Novacoin { @@ -15,9 +31,9 @@ namespace Novacoin /// /// Unsigned integer value /// Byte sequence - public static IList EncodeVarInt(ulong n) + public static byte[] EncodeVarInt(ulong n) { - List resultBytes = new List(); + var resultBytes = new List(); if (n <= 0xfc) { @@ -33,26 +49,26 @@ namespace Novacoin { // ushort flag prefix = 0xfd; - valueBytes = Interop.LEBytes((ushort)n); + valueBytes = BitConverter.GetBytes((ushort)n); } else if (n <= uint.MaxValue) { // uint flag prefix = 0xfe; - valueBytes = Interop.LEBytes((uint)n); + valueBytes = BitConverter.GetBytes((uint)n); } else { // ulong flag prefix = 0xff; - valueBytes = Interop.LEBytes(n); + valueBytes = BitConverter.GetBytes(n); } resultBytes.Add(prefix); resultBytes.AddRange(valueBytes); } - return resultBytes; + return resultBytes.ToArray(); } /// @@ -62,11 +78,31 @@ namespace Novacoin /// /// Integer value /// Byte sequence - public static IList EncodeVarInt(long n) + public static byte[] EncodeVarInt(long n) { return EncodeVarInt((ulong)n); } + public static uint GetEncodedSize(long n) + { + if (n <= 0xfc) + { + return 1; + } + else if (n <= ushort.MaxValue) + { + return 3; + } + else if (n <= uint.MaxValue) + { + return 5; + } + else + { + return 9; + } + } + /// /// Decodes integer value from compact representation /// @@ -74,16 +110,15 @@ namespace Novacoin /// /// Byte sequence /// Integer value - public static ulong DecodeVarInt(IList bytes) + public static ulong DecodeVarInt(byte[] bytes) { - byte prefix = bytes[0]; - - bytes.RemoveAt(0); // Remove prefix - - byte[] bytesArray = bytes.ToArray(); + var prefix = bytes[0]; - if (BitConverter.IsLittleEndian) + if (bytes.Length > 1) { + var bytesArray = new byte[bytes.Length - 1]; + Array.Copy(bytes, 1, bytesArray, 0, bytesArray.Length); + switch (prefix) { case 0xfd: // ushort flag @@ -92,56 +127,28 @@ namespace Novacoin return BitConverter.ToUInt32(bytesArray, 0); case 0xff: // ulong flag return BitConverter.ToUInt64(bytesArray, 0); - default: - return prefix; - } - } - else - { - // Values are stored in little-endian order - switch (prefix) - { - case 0xfd: // ushort flag - Array.Resize(ref bytesArray, 2); - Array.Reverse(bytesArray); - return BitConverter.ToUInt16(bytesArray, 0); - case 0xfe: // uint flag - Array.Resize(ref bytesArray, 4); - Array.Reverse(bytesArray); - return BitConverter.ToUInt32(bytesArray, 0); - case 0xff: // ulong flag - Array.Resize(ref bytesArray, 8); - Array.Reverse(bytesArray); - return BitConverter.ToUInt64(bytesArray, 0); - default: - return prefix; } } + + return prefix; // Values lower than 0xfd are stored directly } - /// - /// Read and decode variable integer from wrapped list object. - /// - /// Note: Should be used only if there is some variable integer data at current position. Otherwise you will get undefined behavior, so make sure that you know what you are doing. - /// - /// - /// - public static ulong ReadVarInt(ref WrappedList wBytes) + public static ulong ReadVarInt(ref BinaryReader reader) { - byte prefix = wBytes.GetItem(); + byte prefix = reader.ReadByte(); switch (prefix) { case 0xfd: // ushort - return Interop.LEBytesToUInt16(wBytes.GetItems(2)); + return reader.ReadUInt16(); case 0xfe: // uint - return Interop.LEBytesToUInt32(wBytes.GetItems(4)); + return reader.ReadUInt32(); case 0xff: // ulong - return Interop.LEBytesToUInt64(wBytes.GetItems(8)); + return reader.ReadUInt64(); default: return prefix; } - } + } }