예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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()));
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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);
        }