コード例 #1
0
        public static IList <byte[]> Decode(byte[] input)
        {
            var message = new RLPMessage(input);

            while (message.Remainder.Offset < input.Length)
            {
                Decode(message);
            }

            return(message.Decoded);
        }
コード例 #2
0
        private static void Decode(RLPMessage msg)
        {
            var firstByte = msg.Remainder.Array[msg.Remainder.Offset];

            if (firstByte == 0x80)
            {
                msg.Decoded.Add(null);
                msg.Remainder = msg.Remainder.Slice(1);
                return;
            }

            // single byte
            if (firstByte <= 0x7f)
            {
                msg.Decoded.Add(new byte[] { firstByte });
                msg.Remainder = msg.Remainder.Slice(1);
                return;
            }

            // string <55 bytes
            if (firstByte <= 0xb7)
            {
                var itemLength = Math.Abs(128 - firstByte);
                var data       = firstByte == 0x80 ? new ArraySegment <byte>(new byte[0]) : msg.Remainder.Slice(1, itemLength);
                msg.Decoded.Add(ArrayManipulator.SubArray(data.Array, data.Offset, data.Count));
                msg.Remainder = msg.Remainder.Slice(data.Count + 1);
                return;
            }

            // string >55 bytes
            if (firstByte <= 0xbf)
            {
                var lengthBytesCount = Math.Abs(LargeItemOffset - firstByte);
                var lengthBytes      = new byte[4];

                var startIndex = Math.Abs(lengthBytesCount - 5) - 1;

                for (int i = 0; i < lengthBytesCount; i++)
                {
                    lengthBytes[startIndex + i] = msg.Remainder.Array[msg.Remainder.Offset + i + 1];
                }

                var itemLength = ByteManipulator.GetUInt32(lengthBytes);

                var data = msg.Remainder.Slice(lengthBytesCount + 1, (int)itemLength);

                msg.Decoded.Add(ArrayManipulator.SubArray(msg.Remainder.Array, data.Offset, data.Count));
                msg.Remainder = msg.Remainder.Slice(data.Count + lengthBytesCount + 1);
                return;
            }

            // collection <55 bytes
            if (firstByte <= 0xf7)
            {
                var itemLength = Math.Abs(192 - firstByte);
                var data       = msg.Remainder.Slice(1, itemLength).ToArray();

                while (msg.Remainder.Offset < msg.Remainder.Array.Length)
                {
                    var decoded = Decode(data);
                    msg.Decoded.AddRange(decoded);
                    msg.Remainder = msg.Remainder.Slice(msg.Remainder.Count);
                }

                return;
            }

            // collection >55 bytes
            if (firstByte <= 0xff)
            {
                var lengthBytesCount = Math.Abs(247 - firstByte);
                var lengthBytes      = new byte[4];

                var startIndex = Math.Abs(lengthBytesCount - 5) - 1;

                for (int i = 0; i < lengthBytesCount; i++)
                {
                    lengthBytes[startIndex + i] = msg.Remainder.Array[msg.Remainder.Offset + i + 1];
                }

                var itemLength = ByteManipulator.GetUInt32(lengthBytes);

                var data = msg.Remainder.Slice(lengthBytesCount + 1, (int)itemLength).ToArray();

                while (msg.Remainder.Offset < msg.Remainder.Array.Length)
                {
                    var decoded = Decode(data);
                    msg.Decoded.AddRange(decoded);
                    msg.Remainder = msg.Remainder.Slice(msg.Remainder.Count);
                }

                return;
            }
        }