private IStackItem DeserializeStackItem(IExecutionEngine engine, BinaryReader reader) { EStackItemType type = (EStackItemType)reader.ReadByte(); switch (type) { case EStackItemType.ByteArray: return(engine.CreateByteArray(reader.ReadVarBytes())); case EStackItemType.Bool: return(engine.CreateBool(reader.ReadBoolean())); case EStackItemType.Integer: return(engine.CreateInteger(new BigInteger(reader.ReadVarBytes()))); case EStackItemType.Array: case EStackItemType.Struct: { IArrayStackItem array; if (type == EStackItemType.Struct) { array = engine.CreateStruct(); } else { array = engine.CreateArray(); } ulong count = reader.ReadVarInt(); while (count-- > 0) { array.Add(DeserializeStackItem(engine, reader)); } return(array); } case EStackItemType.Map: { IMapStackItem map = engine.CreateMap(); ulong count = reader.ReadVarInt(); while (count-- > 0) { IStackItem key = DeserializeStackItem(engine, reader); IStackItem value = DeserializeStackItem(engine, reader); map[key] = value; key.Dispose(); value.Dispose(); } return(map); } default: throw new FormatException(); } }
/// <summary> /// Convert native pointer to stack item /// </summary> /// <param name="engine">Engine</param> /// <param name="item">Item</param> /// <returns>Return StackItem</returns> public static IStackItem ConvertFromNative(this ExecutionEngine engine, IntPtr item) { if (item == IntPtr.Zero) { return(null); } EStackItemType state = (EStackItemType)NeoVM.StackItem_SerializeInfo(item, out int size); if (state == EStackItemType.None) { return(null); } int readed; byte[] payload; if (size > 0) { payload = new byte[size]; fixed(byte *p = payload) { readed = NeoVM.StackItem_Serialize(item, (IntPtr)p, size); } } else { readed = 0; payload = null; } switch (state) { case EStackItemType.Array: return(new ArrayStackItem(engine, item, false)); case EStackItemType.Struct: return(new ArrayStackItem(engine, item, true)); case EStackItemType.Map: return(new MapStackItem(engine, item)); case EStackItemType.Interop: { // Extract object return(new InteropStackItem(engine, item, BitHelper.ToInt32(payload, 0))); } case EStackItemType.ByteArray: return(new ByteArrayStackItem(engine, item, payload ?? (new byte[] { }))); case EStackItemType.Integer: { if (readed != size) { // TODO: Try to fix this issue with BigInteger Array.Resize(ref payload, readed); } return(new IntegerStackItem(engine, item, payload ?? (new byte[] { }))); } case EStackItemType.Bool: return(new BooleanStackItem(engine, item, payload ?? (new byte[] { }))); default: throw new ExternalException(); } }
/// <summary> /// Constructor /// </summary> /// <param name="type">Type</param> protected StackItemBase(EStackItemType type) { Type = type; }
/// <summary> /// Constructor /// </summary> /// <param name="engine">Engine</param> /// <param name="data">Data</param> /// <param name="type">Type</param> protected IStackItem(IExecutionEngine engine, T data, EStackItemType type) : base(engine, type) { Value = data; }
/// <summary> /// Constructor /// </summary> /// <param name="engine">Engine</param> /// <param name="type">Type</param> protected IStackItem(IExecutionEngine engine, EStackItemType type) { Type = type; Engine = engine; }
/// <inheritdoc /> /// <summary> /// Constructor /// </summary> /// <param name="data">Data</param> /// <param name="type">Type</param> protected StackItem(T data, EStackItemType type) : base(type) { Value = data; }