diff --git a/src/Neo/Neo.csproj b/src/Neo/Neo.csproj index 234fbc62c6..130ff2a570 100644 --- a/src/Neo/Neo.csproj +++ b/src/Neo/Neo.csproj @@ -22,4 +22,8 @@ + + + + diff --git a/src/Neo/SmartContract/KeyBuilder.cs b/src/Neo/SmartContract/KeyBuilder.cs index 4648b9baa9..cfd27cc6f8 100644 --- a/src/Neo/SmartContract/KeyBuilder.cs +++ b/src/Neo/SmartContract/KeyBuilder.cs @@ -11,6 +11,7 @@ using Neo.IO; using System; +using System.Buffers.Binary; using System.IO; namespace Neo.SmartContract @@ -29,8 +30,22 @@ public class KeyBuilder /// The prefix of the key. public KeyBuilder(int id, byte prefix) { - Add(id); - this.stream.WriteByte(prefix); + var data = new byte[sizeof(int)]; + BinaryPrimitives.WriteInt32LittleEndian(data, id); + + stream.Write(data); + stream.WriteByte(prefix); + } + + /// + /// Adds part of the key to the builder. + /// + /// Part of the key. + /// A reference to this instance after the add operation has completed. + public KeyBuilder Add(byte key) + { + stream.WriteByte(key); + return this; } /// @@ -60,28 +75,55 @@ public KeyBuilder Add(ISerializable key) } /// - /// Adds part of the key to the builder. + /// Adds part of the key to the builder in BigEndian. /// - /// The type of the parameter. /// Part of the key. /// A reference to this instance after the add operation has completed. - unsafe public KeyBuilder Add(T key) where T : unmanaged + public KeyBuilder AddBigEndian(int key) { - return Add(new ReadOnlySpan(&key, sizeof(T))); + var data = new byte[sizeof(int)]; + BinaryPrimitives.WriteInt32BigEndian(data, key); + + return Add(data); } /// - /// Adds part of the key to the builder with big-endian. + /// Adds part of the key to the builder in BigEndian. /// - /// The type of the parameter. /// Part of the key. /// A reference to this instance after the add operation has completed. - unsafe public KeyBuilder AddBigEndian(T key) where T : unmanaged + public KeyBuilder AddBigEndian(uint key) { - ReadOnlySpan buffer = new(&key, sizeof(T)); - for (int i = buffer.Length - 1; i >= 0; i--) - stream.WriteByte(buffer[i]); - return this; + var data = new byte[sizeof(uint)]; + BinaryPrimitives.WriteUInt32BigEndian(data, key); + + return Add(data); + } + + /// + /// Adds part of the key to the builder in BigEndian. + /// + /// Part of the key. + /// A reference to this instance after the add operation has completed. + public KeyBuilder AddBigEndian(long key) + { + var data = new byte[sizeof(long)]; + BinaryPrimitives.WriteInt64BigEndian(data, key); + + return Add(data); + } + + /// + /// Adds part of the key to the builder in BigEndian. + /// + /// Part of the key. + /// A reference to this instance after the add operation has completed. + public KeyBuilder AddBigEndian(ulong key) + { + var data = new byte[sizeof(ulong)]; + BinaryPrimitives.WriteUInt64BigEndian(data, key); + + return Add(data); } /// diff --git a/tests/Neo.UnitTests/SmartContract/UT_KeyBuilder.cs b/tests/Neo.UnitTests/SmartContract/UT_KeyBuilder.cs index b16c061494..3ff52c1324 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_KeyBuilder.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_KeyBuilder.cs @@ -17,11 +17,6 @@ namespace Neo.UnitTests.SmartContract [TestClass] public class UT_KeyBuilder { - private struct TestKey - { - public int Value; - } - [TestMethod] public void Test() { @@ -39,11 +34,11 @@ public void Test() Assert.AreEqual("010000000203040000000000000000000000000000000000000000", key.ToArray().ToHexString()); key = new KeyBuilder(1, 2); - key = key.Add(new TestKey { Value = 123 }); - Assert.AreEqual("01000000027b000000", key.ToArray().ToHexString()); + key = key.AddBigEndian(123); + Assert.AreEqual("01000000020000007b", key.ToArray().ToHexString()); key = new KeyBuilder(1, 0); - key = key.AddBigEndian(new TestKey { Value = 1 }); + key = key.AddBigEndian(1); Assert.AreEqual("010000000000000001", key.ToArray().ToHexString()); } }