/// <summary> /// Deserializes a <see cref="StackItem"/> from byte array. /// </summary> /// <param name="data">The byte array to parse.</param> /// <param name="limits">The limits for the deserialization.</param> /// <param name="referenceCounter">The <see cref="ReferenceCounter"/> used by the <see cref="StackItem"/>.</param> /// <returns>The deserialized <see cref="StackItem"/>.</returns> public static StackItem Deserialize(byte[] data, ExecutionEngineLimits limits, ReferenceCounter referenceCounter = null) { using MemoryStream ms = new(data, false); using BinaryReader reader = new(ms, Utility.StrictUTF8, true); return(Deserialize(reader, limits with { MaxItemSize = (uint) data.Length }, referenceCounter));
/// <summary> /// Create a new structure with the same content as this structure. All nested structures will be copied by value. /// </summary> /// <param name="limits">Execution engine limits</param> /// <returns>The copied structure.</returns> public Struct Clone(ExecutionEngineLimits limits) { int count = (int)(limits.MaxStackSize - 1); Struct result = new(ReferenceCounter); Queue <Struct> queue = new(); queue.Enqueue(result); queue.Enqueue(this); while (queue.Count > 0) { Struct a = queue.Dequeue(); Struct b = queue.Dequeue(); foreach (StackItem item in b) { count--; if (count < 0) { throw new InvalidOperationException("Beyond clone limits!"); } if (item is Struct sb) { Struct sa = new(ReferenceCounter); a.Add(sa); queue.Enqueue(sa); queue.Enqueue(sb); } else { a.Add(item); } } } return(result); }
/// <summary> /// Deserializes a <see cref="StackItem"/> from byte array. /// </summary> /// <param name="data">The byte array to parse.</param> /// <param name="limits">The limits for the deserialization.</param> /// <param name="referenceCounter">The <see cref="ReferenceCounter"/> used by the <see cref="StackItem"/>.</param> /// <returns>The deserialized <see cref="StackItem"/>.</returns> public static StackItem Deserialize(ReadOnlyMemory <byte> data, ExecutionEngineLimits limits, ReferenceCounter referenceCounter = null) { MemoryReader reader = new(data); return(Deserialize(ref reader, limits with { MaxItemSize = (uint)data.Length }, referenceCounter));
public override bool Equals(StackItem?other, ExecutionEngineLimits limits) { if (other is not Struct s) { return(false); } Stack <StackItem> stack1 = new(); Stack <StackItem> stack2 = new(); stack1.Push(this); stack2.Push(s); uint count = limits.MaxStackSize; while (stack1.Count > 0) { if (count-- == 0) { throw new InvalidOperationException("Too many struct items to compare."); } StackItem a = stack1.Pop(); StackItem b = stack2.Pop(); if (a is Struct sa) { if (ReferenceEquals(a, b)) { continue; } if (b is not Struct sb) { return(false); } if (sa.Count != sb.Count) { return(false); } foreach (StackItem item in sa) { stack1.Push(item); } foreach (StackItem item in sb) { stack2.Push(item); } } else { if (!a.Equals(b)) { return(false); } } } return(true); }
internal override bool Equals(StackItem?other, ExecutionEngineLimits limits) { uint maxComparableSize = limits.MaxComparableSize; return(Equals(other, ref maxComparableSize)); }
/// <summary> /// Deserializes a <see cref="StackItem"/> from <see cref="JObject"/>. /// </summary> /// <param name="json">The <see cref="JObject"/> to deserialize.</param> /// <param name="limits">The limits for the deserialization.</param> /// <param name="referenceCounter">The <see cref="ReferenceCounter"/> used by the <see cref="StackItem"/>.</param> /// <returns>The deserialized <see cref="StackItem"/>.</returns> public static StackItem Deserialize(JObject json, ExecutionEngineLimits limits, ReferenceCounter referenceCounter = null) { uint maxStackSize = limits.MaxStackSize; return(Deserialize(json, ref maxStackSize, referenceCounter)); }
public virtual bool Equals(StackItem?other, ExecutionEngineLimits limits) { return(Equals(other)); }
internal override bool Equals(StackItem?other, ExecutionEngineLimits limits) { if (other is not Struct s) { return(false); } Stack <StackItem> stack1 = new(); Stack <StackItem> stack2 = new(); stack1.Push(this); stack2.Push(s); uint count = limits.MaxStackSize; uint maxComparableSize = limits.MaxComparableSize; while (stack1.Count > 0) { if (count-- == 0) { throw new InvalidOperationException("Too many struct items to compare."); } StackItem a = stack1.Pop(); StackItem b = stack2.Pop(); if (a is ByteString byteString) { if (!byteString.Equals(b, ref maxComparableSize)) { return(false); } } else { if (maxComparableSize == 0) { throw new InvalidOperationException("The operand exceeds the maximum comparable size."); } maxComparableSize -= 1; if (a is Struct sa) { if (ReferenceEquals(a, b)) { continue; } if (b is not Struct sb) { return(false); } if (sa.Count != sb.Count) { return(false); } foreach (StackItem item in sa) { stack1.Push(item); } foreach (StackItem item in sb) { stack2.Push(item); } } else { if (!a.Equals(b)) { return(false); } } } } return(true); }