Merge pull request #35 from nicksavers/master

Use RLP constant instead of magic number
This commit is contained in:
romanman 2014-06-22 13:07:01 +01:00
commit 6a257fb630
1 changed files with 420 additions and 408 deletions

View File

@ -86,7 +86,7 @@ public class RLP {
* \xb9\x04\x00 followed by the string. The range of the first byte is thus * \xb9\x04\x00 followed by the string. The range of the first byte is thus
* [0xb8, 0xbf]. * [0xb8, 0xbf].
*/ */
private static int OFFSET_LONG_ITEM = 0xb8; private static int OFFSET_LONG_ITEM = 0xb7;
/* /*
* If the total payload of a list (i.e. the combined length of all its * If the total payload of a list (i.e. the combined length of all its
@ -112,388 +112,406 @@ public class RLP {
* ******************************************************/ * ******************************************************/
private static byte decodeOneByteItem(byte[] data, int index) { private static byte decodeOneByteItem(byte[] data, int index) {
// null item // null item
if ((data[index] & 0xFF) == OFFSET_SHORT_ITEM) { if ((data[index] & 0xFF) == OFFSET_SHORT_ITEM) {
return (byte) (data[index] - OFFSET_SHORT_ITEM); return (byte) (data[index] - OFFSET_SHORT_ITEM);
} }
// single byte item // single byte item
if ((data[index] & 0xFF) < OFFSET_SHORT_ITEM) { if ((data[index] & 0xFF) < OFFSET_SHORT_ITEM) {
return (byte) (data[index]); return (byte) (data[index]);
} }
// single byte item // single byte item
if ((data[index] & 0xFF) == OFFSET_SHORT_ITEM+1) { if ((data[index] & 0xFF) == OFFSET_SHORT_ITEM + 1) {
return (byte) (data[index + 1]); return (byte) (data[index + 1]);
} }
return 0; return 0;
} }
public static int decodeInt(byte[] data, int index) { public static int decodeInt(byte[] data, int index) {
int value = 0; int value = 0;
if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM && (data[index] & 0xFF) < 0xB7) { if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM
&& (data[index] & 0xFF) < OFFSET_LONG_ITEM) {
byte length = (byte) (data[index] - OFFSET_SHORT_ITEM); byte length = (byte) (data[index] - OFFSET_SHORT_ITEM);
byte pow = (byte) (length - 1); byte pow = (byte) (length - 1);
for (int i = 1; i <= length; ++i) { for (int i = 1; i <= length; ++i) {
value += data[index + i] << (8 * pow); value += data[index + i] << (8 * pow);
pow--; pow--;
} }
} else { } else {
throw new RuntimeException("wrong decode attempt"); throw new RuntimeException("wrong decode attempt");
} }
return value; return value;
} }
private static short decodeShort(byte[] data, int index) { private static short decodeShort(byte[] data, int index) {
short value = 0; short value = 0;
if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM && (data[index] & 0xFF) < 0xB7) { if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM
byte length = (byte) (data[index] - OFFSET_SHORT_ITEM); && (data[index] & 0xFF) < OFFSET_LONG_ITEM) {
value = ByteBuffer.wrap(data, index, length).getShort(); byte length = (byte) (data[index] - OFFSET_SHORT_ITEM);
} else { value = ByteBuffer.wrap(data, index, length).getShort();
value = data[index]; } else {
} value = data[index];
return value; }
} return value;
}
private static long decodeLong(byte[] data, int index) { private static long decodeLong(byte[] data, int index) {
long value = 0; long value = 0;
if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM && (data[index] & 0xFF) < 0xB7) { if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM
&& (data[index] & 0xFF) < OFFSET_LONG_ITEM) {
byte length = (byte) (data[index] - OFFSET_SHORT_ITEM); byte length = (byte) (data[index] - OFFSET_SHORT_ITEM);
byte pow = (byte) (length - 1); byte pow = (byte) (length - 1);
for (int i = 1; i <= length; ++i) { for (int i = 1; i <= length; ++i) {
value += data[index + i] << (8 * pow); value += data[index + i] << (8 * pow);
pow--; pow--;
} }
} else { } else {
throw new RuntimeException("wrong decode attempt"); throw new RuntimeException("wrong decode attempt");
} }
return value; return value;
} }
private static String decodeStringItem(byte[] data, int index) { private static String decodeStringItem(byte[] data, int index) {
String value = null; String value = null;
if ((data[index] & 0xFF) >= 0xB7 && (data[index] & 0xFF) < OFFSET_SHORT_LIST) { if ((data[index] & 0xFF) >= OFFSET_LONG_ITEM
&& (data[index] & 0xFF) < OFFSET_SHORT_LIST) {
byte lengthOfLength = (byte) (data[index] - 0xB7); byte lengthOfLength = (byte) (data[index] - OFFSET_LONG_ITEM);
int length = calcLengthRaw(lengthOfLength, data, index); int length = calcLengthRaw(lengthOfLength, data, index);
value = new String(data, index + lengthOfLength + 1, length); value = new String(data, index + lengthOfLength + 1, length);
} else if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM && (data[index] & 0xFF) < 0xB7) { } else if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM
&& (data[index] & 0xFF) < OFFSET_LONG_ITEM) {
byte length = (byte) ((data[index] & 0xFF) - OFFSET_SHORT_ITEM); byte length = (byte) ((data[index] & 0xFF) - OFFSET_SHORT_ITEM);
value = new String(data, index + 1, length); value = new String(data, index + 1, length);
} else { } else {
throw new RuntimeException("wrong decode attempt"); throw new RuntimeException("wrong decode attempt");
} }
return value; return value;
} }
private static byte[] decodeItemBytes(byte[] data, int index) { private static byte[] decodeItemBytes(byte[] data, int index) {
byte[] value = null; byte[] value = null;
int length = 0; int length = 0;
if ((data[index] & 0xFF) >= 0xB7 && (data[index] & 0xFF) < OFFSET_SHORT_LIST) { if ((data[index] & 0xFF) >= OFFSET_LONG_ITEM
&& (data[index] & 0xFF) < OFFSET_SHORT_LIST) {
byte lengthOfLength = (byte) (data[index] - 0xB7); byte lengthOfLength = (byte) (data[index] - OFFSET_LONG_ITEM);
length = calcLengthRaw(lengthOfLength, data, index); length = calcLengthRaw(lengthOfLength, data, index);
} else if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM && (data[index] & 0xFF) < 0xB7) { } else if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM
&& (data[index] & 0xFF) < OFFSET_LONG_ITEM) {
length = (byte) (data[index] - OFFSET_SHORT_ITEM); length = (byte) (data[index] - OFFSET_SHORT_ITEM);
} else { } else {
throw new RuntimeException("wrong decode attempt"); throw new RuntimeException("wrong decode attempt");
} }
byte[] valueBytes = new byte[length]; byte[] valueBytes = new byte[length];
System.arraycopy(data, index, valueBytes, 0, length); System.arraycopy(data, index, valueBytes, 0, length);
value = valueBytes; value = valueBytes;
return value; return value;
} }
public static BigInteger decodeBigInteger(byte[] data, int index) { public static BigInteger decodeBigInteger(byte[] data, int index) {
BigInteger value = null; BigInteger value = null;
int length = 0; int length = 0;
if ((data[index] & 0xFF) >= 0xB7 && (data[index] & 0xFF) < OFFSET_SHORT_LIST) { if ((data[index] & 0xFF) >= OFFSET_LONG_ITEM
&& (data[index] & 0xFF) < OFFSET_SHORT_LIST) {
byte lengthOfLength = (byte) (data[index] - 0xB7); byte lengthOfLength = (byte) (data[index] - OFFSET_LONG_ITEM);
length = calcLengthRaw(lengthOfLength, data, index); length = calcLengthRaw(lengthOfLength, data, index);
} else if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM && (data[index] & 0xFF) < 0xB7) { } else if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM
&& (data[index] & 0xFF) < OFFSET_LONG_ITEM) {
length = (byte) (data[index] - OFFSET_SHORT_ITEM); length = (byte) (data[index] - OFFSET_SHORT_ITEM);
} else { } else {
throw new RuntimeException("wrong decode attempt"); throw new RuntimeException("wrong decode attempt");
} }
byte[] valueBytes = new byte[length]; byte[] valueBytes = new byte[length];
System.arraycopy(data, index, valueBytes, 0, length); System.arraycopy(data, index, valueBytes, 0, length);
value = new BigInteger(1, valueBytes); value = new BigInteger(1, valueBytes);
return value; return value;
} }
private static byte[] decodeByteArray(byte[] data, int index) { private static byte[] decodeByteArray(byte[] data, int index) {
byte[] value = null; byte[] value = null;
int length = 0; int length = 0;
if ((data[index] & 0xFF) >= 0xB7 && (data[index] & 0xFF) < OFFSET_SHORT_LIST) { if ((data[index] & 0xFF) >= OFFSET_LONG_ITEM
&& (data[index] & 0xFF) < OFFSET_SHORT_LIST) {
byte lengthOfLength = (byte) (data[index] - 0xB7); byte lengthOfLength = (byte) (data[index] - OFFSET_LONG_ITEM);
length = calcLengthRaw(lengthOfLength, data, index); length = calcLengthRaw(lengthOfLength, data, index);
} else if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM && (data[index] & 0xFF) < 0xB7) { } else if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM
&& (data[index] & 0xFF) < OFFSET_LONG_ITEM) {
length = (byte) (data[index] - OFFSET_SHORT_ITEM); length = (byte) (data[index] - OFFSET_SHORT_ITEM);
} else { } else {
throw new RuntimeException("wrong decode attempt"); throw new RuntimeException("wrong decode attempt");
} }
byte[] valueBytes = new byte[length]; byte[] valueBytes = new byte[length];
System.arraycopy(data, index, valueBytes, 0, length); System.arraycopy(data, index, valueBytes, 0, length);
value = valueBytes; value = valueBytes;
return value; return value;
} }
private static int nextItemLength(byte[] data, int index) { private static int nextItemLength(byte[] data, int index) {
if (index >= data.length) if (index >= data.length)
return -1; return -1;
if ((data[index] & 0xFF) >= 0xF7) { if ((data[index] & 0xFF) >= OFFSET_LONG_LIST) {
byte lengthOfLength = (byte) (data[index] - 0xF7); byte lengthOfLength = (byte) (data[index] - OFFSET_LONG_LIST);
int length = calcLength(lengthOfLength, data, index);
return length;
}
if ((data[index] & 0xFF) >= OFFSET_SHORT_LIST && (data[index] & 0xFF) < 0xF7) {
byte length = (byte) ((data[index] & 0xFF) - OFFSET_SHORT_LIST); int length = calcLength(lengthOfLength, data, index);
return length; return length;
} }
if ((data[index] & 0xFF) >= 0xB7 && (data[index] & 0xFF) < OFFSET_SHORT_LIST) { if ((data[index] & 0xFF) >= OFFSET_SHORT_LIST
&& (data[index] & 0xFF) < OFFSET_LONG_LIST) {
byte lengthOfLength = (byte) (data[index] - 0xB7); byte length = (byte) ((data[index] & 0xFF) - OFFSET_SHORT_LIST);
int length = calcLength(lengthOfLength, data, index); return length;
return length; }
} if ((data[index] & 0xFF) >= OFFSET_LONG_ITEM
if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM && (data[index] & 0xFF) < 0xB7) { && (data[index] & 0xFF) < OFFSET_SHORT_LIST) {
byte length = (byte) ((data[index] & 0xFF) - OFFSET_SHORT_ITEM); byte lengthOfLength = (byte) (data[index] - OFFSET_LONG_ITEM);
return length; int length = calcLength(lengthOfLength, data, index);
} return length;
if ((data[index] & 0xFF) == OFFSET_SHORT_ITEM) { }
return 1; if ((data[index] & 0xFF) > OFFSET_SHORT_ITEM
} && (data[index] & 0xFF) < OFFSET_LONG_ITEM) {
if ((data[index] & 0xFF) < OFFSET_SHORT_ITEM) {
return 1;
}
return -1;
}
public static byte[] decodeIP4Bytes(byte[] data, int index) { byte length = (byte) ((data[index] & 0xFF) - OFFSET_SHORT_ITEM);
return length;
}
if ((data[index] & 0xFF) == OFFSET_SHORT_ITEM) {
return 1;
}
if ((data[index] & 0xFF) < OFFSET_SHORT_ITEM) {
return 1;
}
return -1;
}
int length = (data[index] & 0xFF) - OFFSET_SHORT_LIST; public static byte[] decodeIP4Bytes(byte[] data, int index) {
int offset = 1;
byte aByte = decodeOneByteItem(data, index + offset); int length = (data[index] & 0xFF) - OFFSET_SHORT_LIST;
int offset = 1;
if ((data[index + offset] & 0xFF) > OFFSET_SHORT_ITEM) byte aByte = decodeOneByteItem(data, index + offset);
offset = offset + 2;
else
offset = offset + 1;
byte bByte = decodeOneByteItem(data, index + offset);
if ((data[index + offset] & 0xFF) > OFFSET_SHORT_ITEM) if ((data[index + offset] & 0xFF) > OFFSET_SHORT_ITEM)
offset = offset + 2; offset = offset + 2;
else else
offset = offset + 1; offset = offset + 1;
byte cByte = decodeOneByteItem(data, index + offset); byte bByte = decodeOneByteItem(data, index + offset);
if ((data[index + offset] & 0xFF) > OFFSET_SHORT_ITEM) if ((data[index + offset] & 0xFF) > OFFSET_SHORT_ITEM)
offset = offset + 2; offset = offset + 2;
else else
offset = offset + 1; offset = offset + 1;
byte dByte = decodeOneByteItem(data, index + offset); byte cByte = decodeOneByteItem(data, index + offset);
// return IP address if ((data[index + offset] & 0xFF) > OFFSET_SHORT_ITEM)
return new byte[] { aByte, bByte, cByte, dByte } ; offset = offset + 2;
} else
offset = offset + 1;
byte dByte = decodeOneByteItem(data, index + offset);
public static int getFirstListElement(byte[] payload, int pos) { // return IP address
return new byte[] { aByte, bByte, cByte, dByte };
}
if (pos >= payload.length) public static int getFirstListElement(byte[] payload, int pos) {
return -1;
if ((payload[pos] & 0xFF) >= 0xF7) { if (pos >= payload.length)
byte lengthOfLength = (byte) (payload[pos] - 0xF7); return -1;
return pos + lengthOfLength + 1;
}
if ((payload[pos] & 0xFF) >= OFFSET_SHORT_LIST && (payload[pos] & 0xFF) < 0xF7) {
return pos + 1;
}
if ((payload[pos] & 0xFF) >= 0xB7 && (payload[pos] & 0xFF) < OFFSET_SHORT_LIST) {
byte lengthOfLength = (byte) (payload[pos] - 0xB7);
return pos + lengthOfLength + 1;
}
return -1; if ((payload[pos] & 0xFF) >= OFFSET_LONG_LIST) {
} byte lengthOfLength = (byte) (payload[pos] - OFFSET_LONG_LIST);
return pos + lengthOfLength + 1;
}
if ((payload[pos] & 0xFF) >= OFFSET_SHORT_LIST
&& (payload[pos] & 0xFF) < OFFSET_LONG_LIST) {
return pos + 1;
}
if ((payload[pos] & 0xFF) >= OFFSET_LONG_ITEM
&& (payload[pos] & 0xFF) < OFFSET_SHORT_LIST) {
byte lengthOfLength = (byte) (payload[pos] - OFFSET_LONG_ITEM);
return pos + lengthOfLength + 1;
}
return -1;
}
public static int getNextElementIndex(byte[] payload, int pos) { public static int getNextElementIndex(byte[] payload, int pos) {
if (pos >= payload.length) if (pos >= payload.length)
return -1; return -1;
if ((payload[pos] & 0xFF) >= 0xF7) { if ((payload[pos] & 0xFF) >= OFFSET_LONG_LIST) {
byte lengthOfLength = (byte) (payload[pos] - 0xF7); byte lengthOfLength = (byte) (payload[pos] - OFFSET_LONG_LIST);
int length = calcLength(lengthOfLength, payload, pos); int length = calcLength(lengthOfLength, payload, pos);
return pos + lengthOfLength + length + 1; return pos + lengthOfLength + length + 1;
} }
if ((payload[pos] & 0xFF) >= OFFSET_SHORT_LIST && (payload[pos] & 0xFF) < 0xF7) { if ((payload[pos] & 0xFF) >= OFFSET_SHORT_LIST
&& (payload[pos] & 0xFF) < OFFSET_LONG_LIST) {
byte length = (byte) ((payload[pos] & 0xFF) - OFFSET_SHORT_LIST); byte length = (byte) ((payload[pos] & 0xFF) - OFFSET_SHORT_LIST);
return pos + 1 + length; return pos + 1 + length;
} }
if ((payload[pos] & 0xFF) >= 0xB7 && (payload[pos] & 0xFF) < OFFSET_SHORT_LIST) { if ((payload[pos] & 0xFF) >= OFFSET_LONG_ITEM
&& (payload[pos] & 0xFF) < OFFSET_SHORT_LIST) {
byte lengthOfLength = (byte) (payload[pos] - 0xB7); byte lengthOfLength = (byte) (payload[pos] - OFFSET_LONG_ITEM);
int length = calcLength(lengthOfLength, payload, pos); int length = calcLength(lengthOfLength, payload, pos);
return pos + lengthOfLength + length + 1; return pos + lengthOfLength + length + 1;
} }
if ((payload[pos] & 0xFF) > OFFSET_SHORT_ITEM && (payload[pos] & 0xFF) < 0xB7) { if ((payload[pos] & 0xFF) > OFFSET_SHORT_ITEM
&& (payload[pos] & 0xFF) < OFFSET_LONG_ITEM) {
byte length = (byte) ((payload[pos] & 0xFF) - OFFSET_SHORT_ITEM); byte length = (byte) ((payload[pos] & 0xFF) - OFFSET_SHORT_ITEM);
return pos + 1 + length; return pos + 1 + length;
} }
if ((payload[pos] & 0xFF) == OFFSET_SHORT_ITEM) { if ((payload[pos] & 0xFF) == OFFSET_SHORT_ITEM) {
return pos + 1; return pos + 1;
} }
if ((payload[pos] & 0xFF) < OFFSET_SHORT_ITEM) { if ((payload[pos] & 0xFF) < OFFSET_SHORT_ITEM) {
return pos + 1; return pos + 1;
} }
return -1; return -1;
} }
/** /**
* Get exactly one message payload * Get exactly one message payload
*/ */
public static void fullTraverse(byte[] msgData, int level, int startPos, public static void fullTraverse(byte[] msgData, int level, int startPos,
int endPos, int levelToIndex, Queue<Integer> index) { int endPos, int levelToIndex, Queue<Integer> index) {
try {
if (msgData == null || msgData.length == 0) try {
return;
int pos = startPos;
while (pos < endPos) { if (msgData == null || msgData.length == 0)
return;
int pos = startPos;
if (level == levelToIndex) while (pos < endPos) {
index.add(new Integer(pos));
// It's a list with a payload more than 55 bytes if (level == levelToIndex)
// data[0] - 0xF7 = how many next bytes allocated index.add(new Integer(pos));
// for the length of the list
if ((msgData[pos] & 0xFF) >= 0xF7) {
byte lengthOfLength = (byte) (msgData[pos] - 0xF7); // It's a list with a payload more than 55 bytes
int length = calcLength(lengthOfLength, msgData, pos); // data[0] - 0xF7 = how many next bytes allocated
// for the length of the list
if ((msgData[pos] & 0xFF) >= OFFSET_LONG_LIST) {
// now we can parse an item for data[1]..data[length] byte lengthOfLength = (byte) (msgData[pos] - OFFSET_LONG_LIST);
System.out.println("-- level: [" + level int length = calcLength(lengthOfLength, msgData, pos);
+ "] Found big list length: " + length);
fullTraverse(msgData, level + 1, pos + lengthOfLength + 1, // now we can parse an item for data[1]..data[length]
pos + lengthOfLength + length, levelToIndex, index); System.out.println("-- level: [" + level
+ "] Found big list length: " + length);
pos += lengthOfLength + length + 1; fullTraverse(msgData, level + 1, pos + lengthOfLength + 1,
continue; pos + lengthOfLength + length, levelToIndex, index);
}
// It's a list with a payload less than 55 bytes
if ((msgData[pos] & 0xFF) >= OFFSET_SHORT_LIST
&& (msgData[pos] & 0xFF) < 0xF7) {
byte length = (byte) ((msgData[pos] & 0xFF) - OFFSET_SHORT_LIST); pos += lengthOfLength + length + 1;
continue;
}
// It's a list with a payload less than 55 bytes
if ((msgData[pos] & 0xFF) >= OFFSET_SHORT_LIST
&& (msgData[pos] & 0xFF) < OFFSET_LONG_LIST) {
System.out.println("-- level: [" + level byte length = (byte) ((msgData[pos] & 0xFF) - OFFSET_SHORT_LIST);
+ "] Found small list length: " + length);
fullTraverse(msgData, level + 1, pos + 1, pos + length + 1, System.out.println("-- level: [" + level
levelToIndex, index); + "] Found small list length: " + length);
pos += 1 + length; fullTraverse(msgData, level + 1, pos + 1, pos + length + 1,
continue; levelToIndex, index);
}
// 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[pos] & 0xFF) >= 0xB7
&& (msgData[pos] & 0xFF) < OFFSET_SHORT_LIST) {
byte lengthOfLength = (byte) (msgData[pos] - 0xB7); pos += 1 + length;
int length = calcLength(lengthOfLength, msgData, pos); 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[pos] & 0xFF) >= OFFSET_LONG_ITEM
&& (msgData[pos] & 0xFF) < OFFSET_SHORT_LIST) {
// now we can parse an item for data[1]..data[length] byte lengthOfLength = (byte) (msgData[pos] - OFFSET_LONG_ITEM);
System.out.println("-- level: [" + level int length = calcLength(lengthOfLength, msgData, pos);
+ "] Found big item length: " + length);
pos += lengthOfLength + length + 1;
continue; // now we can parse an item for data[1]..data[length]
} System.out.println("-- level: [" + level
// It's an item less than 55 bytes long, + "] Found big item length: " + length);
// data[0] - 0x80 == length of the item pos += lengthOfLength + length + 1;
if ((msgData[pos] & 0xFF) > OFFSET_SHORT_ITEM
&& (msgData[pos] & 0xFF) < 0xB7) {
byte length = (byte) ((msgData[pos] & 0xFF) - OFFSET_SHORT_ITEM); continue;
}
// It's an item less than 55 bytes long,
// data[0] - 0x80 == length of the item
if ((msgData[pos] & 0xFF) > OFFSET_SHORT_ITEM
&& (msgData[pos] & 0xFF) < OFFSET_LONG_ITEM) {
System.out.println("-- level: [" + level byte length = (byte) ((msgData[pos] & 0xFF) - OFFSET_SHORT_ITEM);
+ "] Found small item length: " + length);
pos += 1 + length;
continue;
}
// null item
if ((msgData[pos] & 0xFF) == OFFSET_SHORT_ITEM) {
System.out.println("-- level: [" + level
+ "] Found null item: ");
pos += 1;
continue;
}
// single byte item
if ((msgData[pos] & 0xFF) < OFFSET_SHORT_ITEM) {
System.out.println("-- level: [" + level
+ "] Found single item: ");
pos += 1;
continue;
}
}
} catch (Throwable th) {
throw new RuntimeException("wire packet not parsed correctly",
th.fillInStackTrace());
}
}
private static int calcLength(int lengthOfLength, byte[] msgData, int pos) { System.out.println("-- level: [" + level
byte pow = (byte) (lengthOfLength - 1); + "] Found small item length: " + length);
int length = 0; pos += 1 + length;
for (int i = 1; i <= lengthOfLength; ++i) { continue;
length += (msgData[pos + i] & 0xFF) << (8 * pow); }
pow--; // null item
} if ((msgData[pos] & 0xFF) == OFFSET_SHORT_ITEM) {
return length; System.out.println("-- level: [" + level
} + "] Found null item: ");
pos += 1;
continue;
}
// single byte item
if ((msgData[pos] & 0xFF) < OFFSET_SHORT_ITEM) {
System.out.println("-- level: [" + level
+ "] Found single item: ");
pos += 1;
continue;
}
}
} catch (Throwable th) {
throw new RuntimeException("wire packet not parsed correctly",
th.fillInStackTrace());
}
}
private static int calcLength(int lengthOfLength, byte[] msgData, int pos) {
byte pow = (byte) (lengthOfLength - 1);
int length = 0;
for (int i = 1; i <= lengthOfLength; ++i) {
length += (msgData[pos + i] & 0xFF) << (8 * pow);
pow--;
}
return length;
}
private static int calcLengthRaw(int lengthOfLength, byte[] msgData, int index) { private static int calcLengthRaw(int lengthOfLength, byte[] msgData, int index) {
byte pow = (byte) (lengthOfLength - 1); byte pow = (byte) (lengthOfLength - 1);
@ -527,133 +545,127 @@ public class RLP {
return rlpList; return rlpList;
} }
/** /**
* Get exactly one message payload * Get exactly one message payload
*/ */
private static void fullTraverse(byte[] msgData, int level, int startPos, private static void fullTraverse(byte[] msgData, int level, int startPos,
int endPos, int levelToIndex, RLPList rlpList) { int endPos, int levelToIndex, RLPList rlpList) {
try { try {
if (msgData == null || msgData.length == 0) if (msgData == null || msgData.length == 0)
return; return;
int pos = startPos; int pos = startPos;
while (pos < endPos) { while (pos < endPos) {
// It's a list with a payload more than 55 bytes // It's a list with a payload more than 55 bytes
// data[0] - 0xF7 = how many next bytes allocated // data[0] - 0xF7 = how many next bytes allocated
// for the length of the list // for the length of the list
if ((msgData[pos] & 0xFF) >= 0xF7) { if ((msgData[pos] & 0xFF) >= OFFSET_LONG_LIST) {
byte lengthOfLength = (byte) (msgData[pos] - 0xF7); byte lengthOfLength = (byte) (msgData[pos] - OFFSET_LONG_LIST);
int length = calcLength(lengthOfLength, msgData, pos); int length = calcLength(lengthOfLength, msgData, pos);
byte[] rlpData = new byte[lengthOfLength + length + 1]; byte[] rlpData = new byte[lengthOfLength + length + 1];
System.arraycopy(msgData, pos, rlpData, 0, lengthOfLength System.arraycopy(msgData, pos, rlpData, 0, lengthOfLength
+ length + 1); + length + 1);
RLPList newLevelList = new RLPList(); RLPList newLevelList = new RLPList();
newLevelList.setRLPData(rlpData); newLevelList.setRLPData(rlpData);
// todo: this done to get some data for testing should be fullTraverse(msgData, level + 1, pos + lengthOfLength + 1,
// delete pos + lengthOfLength + length + 1, levelToIndex,
// byte[] subList = Arrays.copyOfRange(msgData, pos, pos + newLevelList);
// lengthOfLength + length + 1); rlpList.add(newLevelList);
// System.out.println(Utils.toHexString(subList));
fullTraverse(msgData, level + 1, pos + lengthOfLength + 1, pos += lengthOfLength + length + 1;
pos + lengthOfLength + length + 1, levelToIndex, continue;
newLevelList); }
rlpList.add(newLevelList); // It's a list with a payload less than 55 bytes
if ((msgData[pos] & 0xFF) >= OFFSET_SHORT_LIST
&& (msgData[pos] & 0xFF) < OFFSET_LONG_LIST) {
pos += lengthOfLength + length + 1; byte length = (byte) ((msgData[pos] & 0xFF) - OFFSET_SHORT_LIST);
continue;
}
// It's a list with a payload less than 55 bytes
if ((msgData[pos] & 0xFF) >= OFFSET_SHORT_LIST
&& (msgData[pos] & 0xFF) < 0xF7) {
byte length = (byte) ((msgData[pos] & 0xFF) - OFFSET_SHORT_LIST); byte[] rlpData = new byte[length + 1];
System.arraycopy(msgData, pos, rlpData, 0, length + 1);
byte[] rlpData = new byte[length + 1]; RLPList newLevelList = new RLPList();
System.arraycopy(msgData, pos, rlpData, 0, length + 1); newLevelList.setRLPData(rlpData);
RLPList newLevelList = new RLPList(); if (length > 0)
newLevelList.setRLPData(rlpData); fullTraverse(msgData, level + 1, pos + 1, pos + length
+ 1, levelToIndex, newLevelList);
rlpList.add(newLevelList);
if (length > 0) pos += 1 + length;
fullTraverse(msgData, level + 1, pos + 1, pos + length continue;
+ 1, levelToIndex, newLevelList); }
rlpList.add(newLevelList); // 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[pos] & 0xFF) >= OFFSET_LONG_ITEM
&& (msgData[pos] & 0xFF) < OFFSET_SHORT_LIST) {
pos += 1 + length; byte lengthOfLength = (byte) (msgData[pos] - OFFSET_LONG_ITEM);
continue; int length = calcLength(lengthOfLength, msgData, pos);
}
// 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[pos] & 0xFF) >= 0xB7
&& (msgData[pos] & 0xFF) < OFFSET_SHORT_LIST) {
byte lengthOfLength = (byte) (msgData[pos] - 0xB7); // now we can parse an item for data[1]..data[length]
int length = calcLength(lengthOfLength, msgData, pos); byte[] item = new byte[length];
System.arraycopy(msgData, pos + lengthOfLength + 1, item,
0, length);
// now we can parse an item for data[1]..data[length] byte[] rlpPrefix = new byte[lengthOfLength + 1];
byte[] item = new byte[length]; System.arraycopy(msgData, pos, rlpPrefix, 0,
System.arraycopy(msgData, pos + lengthOfLength + 1, item, lengthOfLength + 1);
0, length);
byte[] rlpPrefix = new byte[lengthOfLength + 1]; RLPItem rlpItem = new RLPItem(item);
System.arraycopy(msgData, pos, rlpPrefix, 0, rlpList.add(rlpItem);
lengthOfLength + 1); pos += lengthOfLength + length + 1;
RLPItem rlpItem = new RLPItem(item); continue;
rlpList.add(rlpItem); }
pos += lengthOfLength + length + 1; // It's an item less than 55 bytes long,
// data[0] - 0x80 == length of the item
if ((msgData[pos] & 0xFF) > OFFSET_SHORT_ITEM
&& (msgData[pos] & 0xFF) < OFFSET_LONG_ITEM) {
continue; byte length = (byte) ((msgData[pos] & 0xFF) - OFFSET_SHORT_ITEM);
}
// It's an item less than 55 bytes long,
// data[0] - 0x80 == length of the item
if ((msgData[pos] & 0xFF) > OFFSET_SHORT_ITEM
&& (msgData[pos] & 0xFF) < 0xB7) {
byte length = (byte) ((msgData[pos] & 0xFF) - OFFSET_SHORT_ITEM); byte[] item = new byte[length];
System.arraycopy(msgData, pos + 1, item, 0, length);
byte[] item = new byte[length]; byte[] rlpPrefix = new byte[2];
System.arraycopy(msgData, pos + 1, item, 0, length); System.arraycopy(msgData, pos, rlpPrefix, 0, 2);
byte[] rlpPrefix = new byte[2]; RLPItem rlpItem = new RLPItem(item);
System.arraycopy(msgData, pos, rlpPrefix, 0, 2); rlpList.add(rlpItem);
pos += 1 + length;
RLPItem rlpItem = new RLPItem(item); continue;
rlpList.add(rlpItem); }
pos += 1 + length; // null item
if ((msgData[pos] & 0xFF) == OFFSET_SHORT_ITEM) {
byte[] item = new byte[0];
RLPItem rlpItem = new RLPItem(item);
rlpList.add(rlpItem);
pos += 1;
continue;
}
// single byte item
if ((msgData[pos] & 0xFF) < OFFSET_SHORT_ITEM) {
continue; byte[] item = { (byte) (msgData[pos] & 0xFF) };
}
// null item
if ((msgData[pos] & 0xFF) == OFFSET_SHORT_ITEM) {
byte[] item = new byte[0];
RLPItem rlpItem = new RLPItem(item);
rlpList.add(rlpItem);
pos += 1;
continue;
}
// single byte item
if ((msgData[pos] & 0xFF) < OFFSET_SHORT_ITEM) {
byte[] item = { (byte) (msgData[pos] & 0xFF) }; RLPItem rlpItem = new RLPItem(item);
rlpList.add(rlpItem);
RLPItem rlpItem = new RLPItem(item); pos += 1;
rlpList.add(rlpItem); continue;
pos += 1; }
continue; }
} } catch (Exception e) {
}
} catch (Exception e) {
throw new RuntimeException("wire packet not parsed correctly", e); throw new RuntimeException("wire packet not parsed correctly", e);
} }
} }
/** /**
* Reads any RLP encoded byte-array and returns all objects as byte-array or list of byte-arrays * Reads any RLP encoded byte-array and returns all objects as byte-array or list of byte-arrays
@ -676,7 +688,7 @@ public class RLP {
int len = prefix - OFFSET_SHORT_ITEM; // length of the encoded bytes int len = prefix - OFFSET_SHORT_ITEM; // length of the encoded bytes
return new DecodeResult(pos+1+len, copyOfRange(data, pos+1, pos+1+len)); return new DecodeResult(pos+1+len, copyOfRange(data, pos+1, pos+1+len));
} else if (prefix < OFFSET_SHORT_LIST) { } else if (prefix < OFFSET_SHORT_LIST) {
int lenlen = prefix - OFFSET_LONG_ITEM + 1; // length of length the encoded bytes int lenlen = prefix - OFFSET_LONG_ITEM; // length of length the encoded bytes
int lenbytes = byteArrayToInt(copyOfRange(data, pos+1, pos+1+lenlen)); // length of encoded bytes int lenbytes = byteArrayToInt(copyOfRange(data, pos+1, pos+1+lenlen)); // length of encoded bytes
return new DecodeResult(pos+1+lenlen+lenbytes, copyOfRange(data, pos+1+lenlen, pos+1+lenlen+lenbytes)); return new DecodeResult(pos+1+lenlen+lenbytes, copyOfRange(data, pos+1+lenlen, pos+1+lenlen+lenbytes));
} else if (prefix < OFFSET_LONG_LIST) { } else if (prefix < OFFSET_LONG_LIST) {
@ -734,7 +746,7 @@ public class RLP {
return concatenate(prefix, output); return concatenate(prefix, output);
} else { } else {
byte[] inputAsBytes = toBytes(input); byte[] inputAsBytes = toBytes(input);
if(inputAsBytes.length == 1) { if (inputAsBytes.length == 1) {
return inputAsBytes; return inputAsBytes;
} else { } else {
byte[] firstByte = encodeLength(inputAsBytes.length, OFFSET_SHORT_ITEM); byte[] firstByte = encodeLength(inputAsBytes.length, OFFSET_SHORT_ITEM);
@ -750,11 +762,11 @@ public class RLP {
return new byte[] { firstByte }; return new byte[] { firstByte };
} else if (length < MAX_ITEM_LENGTH) { } else if (length < MAX_ITEM_LENGTH) {
byte[] binaryLength; byte[] binaryLength;
if(length > 0xFF) if (length > 0xFF)
binaryLength = BigInteger.valueOf(length).toByteArray(); binaryLength = BigInteger.valueOf(length).toByteArray();
else else
binaryLength = new byte[] { (byte) length }; binaryLength = new byte[] { (byte) length };
byte firstByte = (byte) (binaryLength.length + offset + SIZE_THRESHOLD - 1 ); byte firstByte = (byte) (binaryLength.length + offset + SIZE_THRESHOLD - 1);
return concatenate(new byte[] { firstByte }, binaryLength); return concatenate(new byte[] { firstByte }, binaryLength);
} else { } else {
throw new RuntimeException("Input too long"); throw new RuntimeException("Input too long");
@ -844,7 +856,7 @@ public class RLP {
// first byte = F7 + bytes.length // first byte = F7 + bytes.length
byte[] data = Arrays.copyOf(srcData, srcData.length + 1 + byteNum); byte[] data = Arrays.copyOf(srcData, srcData.length + 1 + byteNum);
System.arraycopy(data, 0, data, 1 + byteNum, srcData.length); System.arraycopy(data, 0, data, 1 + byteNum, srcData.length);
data[0] = (byte) (0xB7 + byteNum); data[0] = (byte) (OFFSET_LONG_ITEM + byteNum);
System.arraycopy(lenBytes, 0, data, 1, lenBytes.length); System.arraycopy(lenBytes, 0, data, 1, lenBytes.length);
return data; return data;
@ -881,7 +893,7 @@ public class RLP {
} }
// first byte = F7 + bytes.length // first byte = F7 + bytes.length
data = new byte[1 + lenBytes.length + totalLength]; data = new byte[1 + lenBytes.length + totalLength];
data[0] = (byte) (0xF7 + byteNum); data[0] = (byte) (OFFSET_LONG_LIST + byteNum);
System.arraycopy(lenBytes, 0, data, 1, lenBytes.length); System.arraycopy(lenBytes, 0, data, 1, lenBytes.length);
copyPos = lenBytes.length + 1; copyPos = lenBytes.length + 1;