public static IList <byte[]> Decode(byte[] input) { var message = new RLPMessage(input); while (message.Remainder.Offset < input.Length) { Decode(message); } return(message.Decoded); }
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; } }