상속: IRLPElement
예제 #1
0
        /// <summary>
        /// Decodes a message from a starting point to an end point
        /// </summary>
        public static void Decode(byte[] msgData, int level, int startPosition,
                                  int endPosition, int levelToIndex, RLPCollection rlpCollection)
        {
            if (msgData == null || msgData.Length == 0)
            {
                return;
            }

            var currentData = new byte[endPosition - startPosition];

            Array.Copy(msgData, startPosition, currentData, 0, currentData.Length);

            try
            {
                var currentPosition = startPosition;

                while (currentPosition < endPosition)
                {
                    // It's a list with a payload more than 55 bytes
                    // data[0] - 0xF7 = how many next bytes allocated
                    // for the length of the list
                    if (msgData[currentPosition] > OFFSET_LONG_LIST)
                    {
                        var lengthOfLength = (byte)(msgData[currentPosition] - OFFSET_LONG_LIST);
                        var length         = CalculateLength(lengthOfLength, msgData, currentPosition);

                        var rlpDataLength = lengthOfLength + length + 1;
                        var rlpData       = new byte[rlpDataLength];

                        Array.Copy(msgData, currentPosition, rlpData, 0, rlpDataLength);
                        var newLevelCollection = new RLPCollection {
                            RLPData = rlpData
                        };

                        Decode(msgData, level + 1, currentPosition + lengthOfLength + 1,
                               currentPosition + rlpDataLength, levelToIndex,
                               newLevelCollection);
                        rlpCollection.Add(newLevelCollection);

                        currentPosition += rlpDataLength;
                        continue;
                    }

                    // It's a list with a payload less than 55 bytes
                    if ((msgData[currentPosition] >= OFFSET_SHORT_LIST) &&
                        (msgData[currentPosition] <= OFFSET_LONG_LIST))
                    {
                        var length        = msgData[currentPosition] - OFFSET_SHORT_LIST;
                        var rlpDataLength = length + 1;
                        var rlpData       = new byte[length + 1];

                        Array.Copy(msgData, currentPosition, rlpData, 0, rlpDataLength);

                        var newLevelCollection = new RLPCollection {
                            RLPData = rlpData
                        };

                        if (length > 0)
                        {
                            Decode(msgData, level + 1, currentPosition + 1, currentPosition + rlpDataLength,
                                   levelToIndex,
                                   newLevelCollection);
                        }

                        rlpCollection.Add(newLevelCollection);

                        currentPosition += rlpDataLength;
                        continue;
                    }
                    // It's an item with a payload more than 55 bytes
                    // data[0] - 0xB7 = how much next bytes allocated for
                    // the length of the string
                    if (msgData[currentPosition] > OFFSET_LONG_ITEM &&
                        msgData[currentPosition] < OFFSET_SHORT_LIST)
                    {
                        var lengthOfLength = (byte)(msgData[currentPosition] - OFFSET_LONG_ITEM);
                        var length         = CalculateLength(lengthOfLength, msgData, currentPosition);

                        // now we can parse an item for data[1]..data[length]
                        var item = new byte[length];
                        Array.Copy(msgData, currentPosition + lengthOfLength + 1, item,
                                   0, length);

                        var rlpPrefix = new byte[lengthOfLength + 1];
                        Array.Copy(msgData, currentPosition, rlpPrefix, 0,
                                   lengthOfLength + 1);

                        var rlpItem = new RLPItem(item);
                        rlpCollection.Add(rlpItem);
                        currentPosition += lengthOfLength + length + 1;

                        continue;
                    }
                    // It's an item less than 55 bytes long,
                    // data[0] - 0x80 == length of the item
                    if (msgData[currentPosition] > OFFSET_SHORT_ITEM &&
                        msgData[currentPosition] <= OFFSET_LONG_ITEM)
                    {
                        var length = (byte)(msgData[currentPosition] - OFFSET_SHORT_ITEM);

                        var item = new byte[length];
                        Array.Copy(msgData, currentPosition + 1, item, 0, length);

                        var rlpPrefix = new byte[2];
                        Array.Copy(msgData, currentPosition, rlpPrefix, 0, 2);

                        var rlpItem = new RLPItem(item);
                        rlpCollection.Add(rlpItem);
                        currentPosition += 1 + length;

                        continue;
                    }
                    // null item
                    if (msgData[currentPosition] == OFFSET_SHORT_ITEM)
                    {
                        var item    = EMPTY_BYTE_ARRAY;
                        var rlpItem = new RLPItem(item);
                        rlpCollection.Add(rlpItem);
                        currentPosition += 1;
                        continue;
                    }
                    // single byte item
                    if (msgData[currentPosition] < OFFSET_SHORT_ITEM)
                    {
                        byte[] item = { msgData[currentPosition] };

                        var rlpItem = new RLPItem(item);
                        rlpCollection.Add(rlpItem);
                        currentPosition += 1;
                    }
                }
            }
            catch (OutOfMemoryException ex)
            {
                throw new Exception(
                          "Invalid RLP (excessive mem allocation while parsing) " + currentData.ToHex(), ex);
            }
            catch (Exception ex)
            {
                throw new Exception(
                          "Invalid RLP " + currentData.ToHex(), ex);
            }
        }
예제 #2
0
파일: RLP.cs 프로젝트: Nethereum/Nethereum
        /// <summary>
        ///     Decodes a message from a starting point to an end point
        /// </summary>
        public static void Decode(byte[] msgData, int level, int startPosition,
            int endPosition, int levelToIndex, RLPCollection rlpCollection)
        {
            if ((msgData == null) || (msgData.Length == 0))
                return;

            var currentData = new byte[endPosition - startPosition];
            Array.Copy(msgData, startPosition, currentData, 0, currentData.Length);

            try
            {
                var currentPosition = startPosition;

                while (currentPosition < endPosition)
                {
                    // It's a list with a payload more than 55 bytes
                    // data[0] - 0xF7 = how many next bytes allocated
                    // for the length of the list
                    if (msgData[currentPosition] > OFFSET_LONG_LIST)
                    {
                        var lengthOfLength = (byte) (msgData[currentPosition] - OFFSET_LONG_LIST);
                        var length = CalculateLength(lengthOfLength, msgData, currentPosition);

                        var rlpDataLength = lengthOfLength + length + 1;
                        var rlpData = new byte[rlpDataLength];

                        Array.Copy(msgData, currentPosition, rlpData, 0, rlpDataLength);
                        var newLevelCollection = new RLPCollection {RLPData = rlpData};

                        Decode(msgData, level + 1, currentPosition + lengthOfLength + 1,
                            currentPosition + rlpDataLength, levelToIndex,
                            newLevelCollection);
                        rlpCollection.Add(newLevelCollection);

                        currentPosition += rlpDataLength;
                        continue;
                    }

                    // It's a list with a payload less than 55 bytes
                    if ((msgData[currentPosition] >= OFFSET_SHORT_LIST)
                        && (msgData[currentPosition] <= OFFSET_LONG_LIST))
                    {
                        var length = msgData[currentPosition] - OFFSET_SHORT_LIST;
                        var rlpDataLength = length + 1;
                        var rlpData = new byte[length + 1];

                        Array.Copy(msgData, currentPosition, rlpData, 0, rlpDataLength);

                        var newLevelCollection = new RLPCollection {RLPData = rlpData};

                        if (length > 0)
                            Decode(msgData, level + 1, currentPosition + 1, currentPosition + rlpDataLength,
                                levelToIndex,
                                newLevelCollection);

                        rlpCollection.Add(newLevelCollection);

                        currentPosition += rlpDataLength;
                        continue;
                    }
                    // It's an item with a payload more than 55 bytes
                    // data[0] - 0xB7 = how much next bytes allocated for
                    // the length of the string
                    if ((msgData[currentPosition] > OFFSET_LONG_ITEM)
                        && (msgData[currentPosition] < OFFSET_SHORT_LIST))
                    {
                        var lengthOfLength = (byte) (msgData[currentPosition] - OFFSET_LONG_ITEM);
                        var length = CalculateLength(lengthOfLength, msgData, currentPosition);

                        // now we can parse an item for data[1]..data[length]
                        var item = new byte[length];
                        Array.Copy(msgData, currentPosition + lengthOfLength + 1, item,
                            0, length);

                        var rlpPrefix = new byte[lengthOfLength + 1];
                        Array.Copy(msgData, currentPosition, rlpPrefix, 0,
                            lengthOfLength + 1);

                        var rlpItem = new RLPItem(item);
                        rlpCollection.Add(rlpItem);
                        currentPosition += lengthOfLength + length + 1;

                        continue;
                    }
                    // It's an item less than 55 bytes long,
                    // data[0] - 0x80 == length of the item
                    if ((msgData[currentPosition] > OFFSET_SHORT_ITEM)
                        && (msgData[currentPosition] <= OFFSET_LONG_ITEM))
                    {
                        var length = (byte) (msgData[currentPosition] - OFFSET_SHORT_ITEM);

                        var item = new byte[length];
                        Array.Copy(msgData, currentPosition + 1, item, 0, length);

                        var rlpPrefix = new byte[2];
                        Array.Copy(msgData, currentPosition, rlpPrefix, 0, 2);

                        var rlpItem = new RLPItem(item);
                        rlpCollection.Add(rlpItem);
                        currentPosition += 1 + length;

                        continue;
                    }
                    // null item
                    if (msgData[currentPosition] == OFFSET_SHORT_ITEM)
                    {
                        var item = EMPTY_BYTE_ARRAY;
                        var rlpItem = new RLPItem(item);
                        rlpCollection.Add(rlpItem);
                        currentPosition += 1;
                        continue;
                    }
                    // single byte item
                    if (msgData[currentPosition] < OFFSET_SHORT_ITEM)
                    {
                        byte[] item = {msgData[currentPosition]};

                        var rlpItem = new RLPItem(item);
                        rlpCollection.Add(rlpItem);
                        currentPosition += 1;
                    }
                }
            }
            catch (OutOfMemoryException ex)
            {
                throw new Exception(
                    "Invalid RLP (excessive mem allocation while parsing) " + currentData.ToHex(), ex);
            }
            catch (Exception ex)
            {
                throw new Exception(
                    "Invalid RLP " + currentData.ToHex(), ex);
            }
        }