public override void Decode(ref AbiDecodeBuffer buff, out string val) { var uintEncoder = UInt256Encoder.UncheckedEncoders.Get(); try { // Read the next header int which is the offset to the start of the data // in the data payload area. uintEncoder.Decode(buff.HeadCursor, out int startingPosition); // The first int in our offset of data area is the length of the rest of the payload. var encodedLength = buff.Buffer.Slice(startingPosition, UInt256.SIZE); uintEncoder.Decode(encodedLength, out int byteLen); // Read the actual payload from the data area var encodedString = buff.Buffer.Slice(startingPosition + UInt256.SIZE, byteLen); var bytes = new byte[byteLen]; encodedString.CopyTo(bytes); val = UTF8.GetString(bytes); int bodyLen = PadLength(bytes.Length, UInt256.SIZE); buff.IncrementHeadCursor(UInt256.SIZE); } finally { UInt256Encoder.UncheckedEncoders.Put(uintEncoder); } }
public void Decode(ref AbiDecodeBuffer buff, out TItem[] val) { var uintEncoder = UInt256Encoder.UncheckedEncoders.Get(); try { // Read the next header int which is the offset to the start of the data // in the data payload area. uintEncoder.Decode(buff.HeadCursor, out int startingPosition); // The first int in our offset of data area is the length of the rest of the payload. var encodedLength = buff.Buffer.Slice(startingPosition, UInt256.SIZE); uintEncoder.Decode(encodedLength, out int itemCount); var payloadOffset = startingPosition + UInt256.SIZE; var payload = buff.Buffer.Slice(payloadOffset, buff.Buffer.Length - payloadOffset); var payloadBuffer = new AbiDecodeBuffer(payload, Enumerable.Repeat(_info.ArrayItemInfo, itemCount).ToArray()); var items = new TItem[itemCount]; for (var i = 0; i < itemCount; i++) { _itemEncoder.Decode(ref payloadBuffer, out var item); items[i] = item; } val = items; buff.IncrementHeadCursor(UInt256.SIZE); } finally { UInt256Encoder.UncheckedEncoders.Put(uintEncoder); } }
public override void Decode(ref AbiDecodeBuffer buff, out bool val) { // Input data validity check: last byte should be either 0 or 1. switch (buff.HeadCursor[31]) { case 0: val = false; break; case 1: val = true; break; default: throw Error(buff.HeadCursor); } #if ZERO_BYTE_CHECKS // Input data validity check: all but the last byte should be zero. // Span<byte>.SequenceEquals should use the fast native memory slab comparer. if (!buff.HeadCursor.Slice(0, UInt256.SIZE - 1).SequenceEqual(ZEROx31)) { throw Error(buff.HeadCursor.Slice(0, UInt256.SIZE - 1)); } #endif buff.IncrementHeadCursor(UInt256.SIZE); Exception Error(ReadOnlySpan <byte> payload) { return(new ArgumentException("Invalid boolean input data; should be 31 zeros followed by a 1 or 0; received: " + payload.Slice(0, UInt256.SIZE).ToHexString())); } }
public override void Decode(ref AbiDecodeBuffer buff, out Address val) { #if ZERO_BYTE_CHECKS // data validity check: 20 address bytes should be left-padded with 12 zero-bytes if (!buff.HeadCursor.Slice(0, 12).SequenceEqual(ZEROx12)) { throw new ArgumentException("Invalid address input data; should be 20 address bytes, left-padded with 12 zero-bytes; received: " + buff.HeadCursor.Slice(0, UInt256.SIZE).ToHexString()); } #endif val = MemoryMarshal.Read <Address>(buff.HeadCursor.Slice(12)); buff.IncrementHeadCursor(UInt256.SIZE); }
public override void Decode(ref AbiDecodeBuffer buff, out IEnumerable <byte> val) { var uintEncoder = UInt256Encoder.UncheckedEncoders.Get(); try { // Read the next header int which is the offset to the start of the data // in the data payload area. uintEncoder.Decode(buff.HeadCursor, out int startingPosition); // The first int in our offset of data area is the length of the rest of the payload. var encodedLength = buff.Buffer.Slice(startingPosition, UInt256.SIZE); uintEncoder.Decode(encodedLength, out int byteLen); // Read the actual payload from the data area var payloadOffset = startingPosition + UInt256.SIZE; var payload = buff.Buffer.Slice(payloadOffset, byteLen); var bytes = payload.ToArray(); int bodyLen = PadLength(bytes.Length, UInt256.SIZE); val = bytes; #if ZERO_BYTE_CHECKS // data validity check: should be right-padded with zero bytes for (var i = payloadOffset + byteLen; i < payloadOffset + bodyLen; i++) { if (buff.Buffer[i] != 0) { throw new ArgumentException($"Invalid bytes input data; should be {bytes.Length} bytes of data followed by {bodyLen - bytes.Length} zero-bytes"); } } #endif buff.IncrementHeadCursor(UInt256.SIZE); } finally { UInt256Encoder.UncheckedEncoders.Put(uintEncoder); } }
public override void Decode(ref AbiDecodeBuffer buff, out IEnumerable <byte> val) { var bytes = new byte[_info.ArrayLength]; for (var i = 0; i < bytes.Length; i++) { bytes[i] = buff.HeadCursor[i]; } #if ZERO_BYTE_CHECKS // data validity check: all bytes after the fixed M amount should be zero for (var i = bytes.Length; i < UInt256.SIZE; i++) { if (buff.HeadCursor[i] != 0) { throw new ArgumentException($"Invalid {_info.SolidityName} input data; should be {_info.ArrayLength} bytes padded {UInt256.SIZE - _info.ArrayLength} zero-bytes; received: " + buff.HeadCursor.Slice(0, 32).ToHexString()); } } #endif val = bytes; buff.IncrementHeadCursor(UInt256.SIZE); }