mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-12 02:05:53 +00:00
Give VarInt a concept of originally serialized size.
VarInts have multiple encodings, and during parsing we need to know the size of the actually encoded form, not the size of the optimal encoding.
This commit is contained in:
parent
95b5e0d894
commit
009939f9be
@ -439,7 +439,7 @@ public abstract class Message implements Serializable {
|
|||||||
|
|
||||||
long readVarInt(int offset) {
|
long readVarInt(int offset) {
|
||||||
VarInt varint = new VarInt(bytes, cursor + offset);
|
VarInt varint = new VarInt(bytes, cursor + offset);
|
||||||
cursor += offset + varint.getSizeInBytes();
|
cursor += offset + varint.getOriginalSizeInBytes();
|
||||||
return varint.value;
|
return varint.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,7 +462,7 @@ public abstract class Message implements Serializable {
|
|||||||
cursor += 1;
|
cursor += 1;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
cursor += varInt.getSizeInBytes();
|
cursor += varInt.getOriginalSizeInBytes();
|
||||||
byte[] characters = new byte[(int) varInt.value];
|
byte[] characters = new byte[(int) varInt.value];
|
||||||
System.arraycopy(bytes, cursor, characters, 0, characters.length);
|
System.arraycopy(bytes, cursor, characters, 0, characters.length);
|
||||||
cursor += characters.length;
|
cursor += characters.length;
|
||||||
|
@ -444,7 +444,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
|||||||
|
|
||||||
varint = new VarInt(buf, cursor);
|
varint = new VarInt(buf, cursor);
|
||||||
long txInCount = varint.value;
|
long txInCount = varint.value;
|
||||||
cursor += varint.getSizeInBytes();
|
cursor += varint.getOriginalSizeInBytes();
|
||||||
|
|
||||||
for (i = 0; i < txInCount; i++) {
|
for (i = 0; i < txInCount; i++) {
|
||||||
// 36 = length of previous_outpoint
|
// 36 = length of previous_outpoint
|
||||||
@ -452,19 +452,19 @@ public class Transaction extends ChildMessage implements Serializable {
|
|||||||
varint = new VarInt(buf, cursor);
|
varint = new VarInt(buf, cursor);
|
||||||
scriptLen = varint.value;
|
scriptLen = varint.value;
|
||||||
// 4 = length of sequence field (unint32)
|
// 4 = length of sequence field (unint32)
|
||||||
cursor += scriptLen + 4 + varint.getSizeInBytes();
|
cursor += scriptLen + 4 + varint.getOriginalSizeInBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
varint = new VarInt(buf, cursor);
|
varint = new VarInt(buf, cursor);
|
||||||
long txOutCount = varint.value;
|
long txOutCount = varint.value;
|
||||||
cursor += varint.getSizeInBytes();
|
cursor += varint.getOriginalSizeInBytes();
|
||||||
|
|
||||||
for (i = 0; i < txOutCount; i++) {
|
for (i = 0; i < txOutCount; i++) {
|
||||||
// 8 = length of tx value field (uint64)
|
// 8 = length of tx value field (uint64)
|
||||||
cursor += 8;
|
cursor += 8;
|
||||||
varint = new VarInt(buf, cursor);
|
varint = new VarInt(buf, cursor);
|
||||||
scriptLen = varint.value;
|
scriptLen = varint.value;
|
||||||
cursor += scriptLen + varint.getSizeInBytes();
|
cursor += scriptLen + varint.getOriginalSizeInBytes();
|
||||||
}
|
}
|
||||||
// 4 = length of lock_time field (uint32)
|
// 4 = length of lock_time field (uint32)
|
||||||
return cursor - offset + 4;
|
return cursor - offset + 4;
|
||||||
|
@ -20,9 +20,11 @@ import static com.google.bitcoin.core.Utils.isLessThanUnsigned;
|
|||||||
|
|
||||||
public class VarInt {
|
public class VarInt {
|
||||||
public final long value;
|
public final long value;
|
||||||
|
private final int originallyEncodedSize;
|
||||||
|
|
||||||
public VarInt(long value) {
|
public VarInt(long value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
originallyEncodedSize = getSizeInBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
// BitCoin has its own varint format, known in the C++ source as "compact size".
|
// BitCoin has its own varint format, known in the C++ source as "compact size".
|
||||||
@ -32,23 +34,41 @@ public class VarInt {
|
|||||||
if (first < 253) {
|
if (first < 253) {
|
||||||
// 8 bits.
|
// 8 bits.
|
||||||
val = first;
|
val = first;
|
||||||
|
originallyEncodedSize = 1;
|
||||||
} else if (first == 253) {
|
} else if (first == 253) {
|
||||||
// 16 bits.
|
// 16 bits.
|
||||||
val = (0xFF & buf[offset + 1]) | ((0xFF & buf[offset + 2]) << 8);
|
val = (0xFF & buf[offset + 1]) | ((0xFF & buf[offset + 2]) << 8);
|
||||||
|
originallyEncodedSize = 3;
|
||||||
} else if (first == 254) {
|
} else if (first == 254) {
|
||||||
// 32 bits.
|
// 32 bits.
|
||||||
val = Utils.readUint32(buf, offset + 1);
|
val = Utils.readUint32(buf, offset + 1);
|
||||||
|
originallyEncodedSize = 5;
|
||||||
} else {
|
} else {
|
||||||
// 64 bits.
|
// 64 bits.
|
||||||
val = Utils.readUint32(buf, offset + 1) | (Utils.readUint32(buf, offset + 5) << 32);
|
val = Utils.readUint32(buf, offset + 1) | (Utils.readUint32(buf, offset + 5) << 32);
|
||||||
|
originallyEncodedSize = 9;
|
||||||
}
|
}
|
||||||
this.value = val;
|
this.value = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of bytes used to encode this originally if deserialized from a byte array.
|
||||||
|
* Otherwise returns the minimum encoded size
|
||||||
|
*/
|
||||||
|
public int getOriginalSizeInBytes() {
|
||||||
|
return originallyEncodedSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the minimum encoded size of the value stored in this VarInt
|
||||||
|
*/
|
||||||
public int getSizeInBytes() {
|
public int getSizeInBytes() {
|
||||||
return sizeOf(value);
|
return sizeOf(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the minimum encoded size of the given value.
|
||||||
|
*/
|
||||||
public static int sizeOf(int value) {
|
public static int sizeOf(int value) {
|
||||||
// Java doesn't have the actual value of MAX_INT, as all types in Java are signed.
|
// Java doesn't have the actual value of MAX_INT, as all types in Java are signed.
|
||||||
if (value < 253)
|
if (value < 253)
|
||||||
@ -58,6 +78,9 @@ public class VarInt {
|
|||||||
return 5; // 1 marker + 4 data bytes
|
return 5; // 1 marker + 4 data bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the minimum encoded size of the given value.
|
||||||
|
*/
|
||||||
public static int sizeOf(long value) {
|
public static int sizeOf(long value) {
|
||||||
// Java doesn't have the actual value of MAX_INT, as all types in Java are signed.
|
// Java doesn't have the actual value of MAX_INT, as all types in Java are signed.
|
||||||
if (isLessThanUnsigned(value, 253))
|
if (isLessThanUnsigned(value, 253))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user