static UInt160 ToUInt160(Neo.VM.Types.StackItem item) { if (item.Type != Neo.VM.Types.StackItemType.ByteString) { throw new Exception($"Unexpected result stack type {item.Type}"); } if (item.GetSpan().Length != UInt160.Length) { throw new Exception($"Unexpected result stack length {item.GetSpan().Length}"); } return(new UInt160(item.GetSpan())); }
public static JToken ToJson(this StackItem item) { return item switch { Neo.VM.Types.Boolean _ => item.GetBoolean(), Neo.VM.Types.Buffer buffer => buffer.GetSpan().ToHexString(), Neo.VM.Types.ByteString byteString => byteString.GetSpan().ToHexString(), Neo.VM.Types.Integer @int => @int.GetInteger().ToString(), // Neo.VM.Types.InteropInterface _ => MakeVariable("InteropInterface"), Neo.VM.Types.Map map => MapToJson(map), Neo.VM.Types.Null _ => new JValue((object?)null), // Neo.VM.Types.Pointer _ => MakeVariable("Pointer"), Neo.VM.Types.Array array => new JArray(array.Select(i => i.ToJson())), _ => throw new NotSupportedException(), };
static UInt160 ToUInt160(Neo.VM.Types.StackItem item) { if (item.IsNull) { return(UInt160.Zero); } var bytes = item.GetSpan(); return(bytes.Length == 0 ? UInt160.Zero : bytes.Length == 20 ? new UInt160(bytes) : throw new ArgumentException("invalid UInt160", nameof(item))); }
static int GetSize(Neo.VM.Types.StackItem item, uint maxSize) { int size = 0; var serialized = new List <Neo.VM.Types.CompoundType>(); var unserialized = new Stack <Neo.VM.Types.StackItem>(); unserialized.Push(item); while (unserialized.Count > 0) { item = unserialized.Pop(); size++; switch (item) { case Neo.VM.Types.Null _: break; case Neo.VM.Types.Boolean _: size += sizeof(bool); break; case Neo.VM.Types.Integer _: case Neo.VM.Types.ByteString _: case Neo.VM.Types.Buffer _: { var span = item.GetSpan(); size += Neo.IO.Helper.GetVarSize(span.Length); size += span.Length; } break; case Neo.VM.Types.Array array: if (serialized.Any(p => ReferenceEquals(p, array))) { throw new NotSupportedException(); } serialized.Add(array); size += Neo.IO.Helper.GetVarSize(array.Count); for (int i = array.Count - 1; i >= 0; i--) { unserialized.Push(array[i]); } break; case Neo.VM.Types.Map map: if (serialized.Any(p => ReferenceEquals(p, map))) { throw new NotSupportedException(); } serialized.Add(map); size += Neo.IO.Helper.GetVarSize(map.Count); foreach (var pair in map.Reverse()) { unserialized.Push(pair.Value); unserialized.Push(pair.Key); } break; default: throw new NotSupportedException(); } } if (size > maxSize) { throw new InvalidOperationException(); } return(size); }
static async Task WriteStackItemAsync(System.IO.TextWriter writer, Neo.VM.Types.StackItem item, int indent = 1, string prefix = "") { switch (item) { case Neo.VM.Types.Boolean _: await WriteLineAsync(item.GetBoolean()? "true" : "false").ConfigureAwait(false); break; case Neo.VM.Types.Integer @int: await WriteLineAsync(@int.GetInteger().ToString()).ConfigureAwait(false); break; case Neo.VM.Types.Buffer buffer: await WriteLineAsync(Neo.Helper.ToHexString(buffer.GetSpan())).ConfigureAwait(false); break; case Neo.VM.Types.ByteString byteString: await WriteLineAsync(Neo.Helper.ToHexString(byteString.GetSpan())).ConfigureAwait(false); break; case Neo.VM.Types.Null _: await WriteLineAsync("<null>").ConfigureAwait(false); break; case Neo.VM.Types.Array array: await WriteLineAsync($"Array: ({array.Count})").ConfigureAwait(false); for (int i = 0; i < array.Count; i++) { await WriteStackItemAsync(writer, array[i], indent + 1).ConfigureAwait(false); } break; case Neo.VM.Types.Map map: await WriteLineAsync($"Map: ({map.Count})").ConfigureAwait(false); foreach (var m in map) { await WriteStackItemAsync(writer, m.Key, indent + 1, "key: ").ConfigureAwait(false); await WriteStackItemAsync(writer, m.Value, indent + 1, "value: ").ConfigureAwait(false); } break; } async Task WriteLineAsync(string value) { for (var i = 0; i < indent; i++) { await writer.WriteAsync(" ").ConfigureAwait(false); } if (!string.IsNullOrEmpty(prefix)) { await writer.WriteAsync(prefix).ConfigureAwait(false); } await writer.WriteLineAsync(value).ConfigureAwait(false); } }