From c8b4e39883f22978a43ce9f461e72c1fe98c7251 Mon Sep 17 00:00:00 2001 From: Shargon Date: Sun, 8 Nov 2020 10:23:29 +0100 Subject: [PATCH] Add Itoa atoi syscalls (#2043) * Itoa atoi * add base * Update src/neo/SmartContract/ApplicationEngine.Binary.cs Co-authored-by: Erik Zhang * Update src/neo/SmartContract/ApplicationEngine.Binary.cs Co-authored-by: Erik Zhang * Fix ut * Clean code * Update src/neo/SmartContract/ApplicationEngine.Binary.cs Co-authored-by: Erik Zhang * Update src/neo/SmartContract/ApplicationEngine.Binary.cs Co-authored-by: Erik Zhang * Fix ut Co-authored-by: Erik Zhang --- .../SmartContract/ApplicationEngine.Binary.cs | 25 +++++++++++++++++++ .../SmartContract/UT_ApplicationEngine.cs | 17 +++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/neo/SmartContract/ApplicationEngine.Binary.cs b/src/neo/SmartContract/ApplicationEngine.Binary.cs index 263fe3d49f..78faa488b5 100644 --- a/src/neo/SmartContract/ApplicationEngine.Binary.cs +++ b/src/neo/SmartContract/ApplicationEngine.Binary.cs @@ -1,5 +1,8 @@ using Neo.Cryptography; using Neo.VM.Types; +using System; +using System.Globalization; +using System.Numerics; using static System.Convert; namespace Neo.SmartContract @@ -12,6 +15,8 @@ partial class ApplicationEngine public static readonly InteropDescriptor System_Binary_Base64Decode = Register("System.Binary.Base64Decode", nameof(Base64Decode), 0_00100000, CallFlags.None, true); public static readonly InteropDescriptor System_Binary_Base58Encode = Register("System.Binary.Base58Encode", nameof(Base58Encode), 0_00100000, CallFlags.None, true); public static readonly InteropDescriptor System_Binary_Base58Decode = Register("System.Binary.Base58Decode", nameof(Base58Decode), 0_00100000, CallFlags.None, true); + public static readonly InteropDescriptor System_Binary_Itoa = Register("System.Binary.Itoa", nameof(Itoa), 0_00100000, CallFlags.None, true); + public static readonly InteropDescriptor System_Binary_Atoi = Register("System.Binary.Atoi", nameof(Atoi), 0_00100000, CallFlags.None, true); protected internal byte[] BinarySerialize(StackItem item) { @@ -23,6 +28,26 @@ protected internal StackItem BinaryDeserialize(byte[] data) return BinarySerializer.Deserialize(data, Limits.MaxStackSize, Limits.MaxItemSize, ReferenceCounter); } + protected internal string Itoa(BigInteger value, int @base) + { + return @base switch + { + 10 => value.ToString(), + 16 => value.ToString("x"), + _ => throw new ArgumentOutOfRangeException(nameof(@base)) + }; + } + + protected internal BigInteger Atoi(string value, int @base) + { + return @base switch + { + 10 => BigInteger.Parse(value), + 16 => BigInteger.Parse(value, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture), + _ => throw new ArgumentOutOfRangeException(nameof(@base)) + }; + } + protected internal string Base64Encode(byte[] data) { return ToBase64String(data); diff --git a/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs b/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs index d625f95689..36a67f026c 100644 --- a/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs +++ b/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs @@ -3,6 +3,7 @@ using Neo.Ledger; using Neo.SmartContract; using Neo.VM.Types; +using System.Numerics; namespace Neo.UnitTests.SmartContract { @@ -38,6 +39,22 @@ public void TestBinary() Assert.AreEqual("2VfUX", engine.Base58Encode(new byte[] { 1, 2, 3, 4 })); } + [TestMethod] + public void TestItoaAtoi() + { + using var engine = ApplicationEngine.Create(TriggerType.Application, null, null); + + Assert.AreEqual("1", engine.Itoa(BigInteger.One, 10)); + Assert.AreEqual("1", engine.Itoa(BigInteger.One, 16)); + Assert.AreEqual("-1", engine.Itoa(BigInteger.MinusOne, 10)); + Assert.AreEqual("f", engine.Itoa(BigInteger.MinusOne, 16)); + Assert.AreEqual(-1, engine.Atoi("-1", 10)); + Assert.AreEqual(1, engine.Atoi("+1", 10)); + Assert.AreEqual(-1, engine.Atoi("ff", 16)); + Assert.ThrowsException(() => engine.Atoi("a", 10)); + Assert.ThrowsException(() => engine.Atoi("a", 11)); + } + [TestMethod] public void TestNotify() {