private static JObject ToJson(StackItem item, HashSet <StackItem> context) { JObject json = new(); json["type"] = item.Type; switch (item) { case Array array: context ??= new HashSet <StackItem>(ReferenceEqualityComparer.Instance); if (!context.Add(array)) { throw new InvalidOperationException(); } json["value"] = new JArray(array.Select(p => ToJson(p, context))); break; case Boolean boolean: json["value"] = boolean.GetBoolean(); break; case Buffer _: case ByteString _: json["value"] = Convert.ToBase64String(item.GetSpan()); break; case Integer integer: json["value"] = integer.GetInteger().ToString(); break; case Map map: context ??= new HashSet <StackItem>(ReferenceEqualityComparer.Instance); if (!context.Add(map)) { throw new InvalidOperationException(); } json["value"] = new JArray(map.Select(p => { JObject item = new(); item["key"] = ToJson(p.Key, context); item["value"] = ToJson(p.Value, context); return(item); })); break; case Pointer pointer: json["value"] = pointer.Position; break; } return(json); }
public static string GetString(this StackItem item) { return(Encoding.UTF8.GetString(item.GetSpan())); }
private static ContractParameter ToParameter(StackItem item, List<Tuple<StackItem, ContractParameter>> context) { ContractParameter parameter = null; switch (item) { case VMArray array: if (context is null) context = new List<Tuple<StackItem, ContractParameter>>(); else parameter = context.FirstOrDefault(p => ReferenceEquals(p.Item1, item))?.Item2; if (parameter is null) { parameter = new ContractParameter { Type = ContractParameterType.Array }; context.Add(new Tuple<StackItem, ContractParameter>(item, parameter)); parameter.Value = array.Select(p => ToParameter(p, context)).ToList(); } break; case Map map: if (context is null) context = new List<Tuple<StackItem, ContractParameter>>(); else parameter = context.FirstOrDefault(p => ReferenceEquals(p.Item1, item))?.Item2; if (parameter is null) { parameter = new ContractParameter { Type = ContractParameterType.Map }; context.Add(new Tuple<StackItem, ContractParameter>(item, parameter)); parameter.Value = map.Select(p => new KeyValuePair<ContractParameter, ContractParameter>(ToParameter(p.Key, context), ToParameter(p.Value, context))).ToList(); } break; case VMBoolean _: parameter = new ContractParameter { Type = ContractParameterType.Boolean, Value = item.ToBoolean() }; break; case ByteArray _: parameter = new ContractParameter { Type = ContractParameterType.ByteArray, Value = item.GetSpan().ToArray() }; break; case Integer _: parameter = new ContractParameter { Type = ContractParameterType.Integer, Value = item.GetBigInteger() }; break; case InteropInterface _: parameter = new ContractParameter { Type = ContractParameterType.InteropInterface }; break; default: // Null included throw new ArgumentException(); } return parameter; }