Skip to content

Commit 2a1294f

Browse files
authored
Merge pull request #1978 from mikecat/use-bigint-for-varint
Use BigInt for encoding/decoding VarInt
2 parents 314a14a + fb968da commit 2a1294f

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed

src/core/operations/VarIntDecode.mjs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class VarIntDecode extends Operation {
2424
this.description = "Decodes a VarInt encoded integer. VarInt is an efficient way of encoding variable length integers and is commonly used with Protobuf.";
2525
this.infoURL = "https://developers.google.com/protocol-buffers/docs/encoding#varints";
2626
this.inputType = "byteArray";
27-
this.outputType = "number";
27+
this.outputType = "string";
2828
this.args = [];
2929
}
3030

@@ -35,7 +35,18 @@ class VarIntDecode extends Operation {
3535
*/
3636
run(input, args) {
3737
try {
38-
return Protobuf.varIntDecode(input);
38+
if (typeof BigInt === "function") {
39+
let result = BigInt(0);
40+
let offset = BigInt(0);
41+
for (let i = 0; i < input.length; i++) {
42+
result |= BigInt(input[i] & 0x7f) << offset;
43+
if (!(input[i] & 0x80)) break;
44+
offset += BigInt(7);
45+
}
46+
return result.toString();
47+
} else {
48+
return Protobuf.varIntDecode(input).toString();
49+
}
3950
} catch (err) {
4051
throw new OperationError(err);
4152
}

src/core/operations/VarIntEncode.mjs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,31 @@ class VarIntEncode extends Operation {
2323
this.module = "Default";
2424
this.description = "Encodes a Vn integer as a VarInt. VarInt is an efficient way of encoding variable length integers and is commonly used with Protobuf.";
2525
this.infoURL = "https://developers.google.com/protocol-buffers/docs/encoding#varints";
26-
this.inputType = "number";
26+
this.inputType = "string";
2727
this.outputType = "byteArray";
2828
this.args = [];
2929
}
3030

3131
/**
32-
* @param {number} input
32+
* @param {string} input
3333
* @param {Object[]} args
3434
* @returns {byteArray}
3535
*/
3636
run(input, args) {
3737
try {
38-
return Protobuf.varIntEncode(input);
38+
if (typeof BigInt === "function") {
39+
let value = BigInt(input);
40+
if (value < 0) throw new OperationError("Negative values cannot be represented as VarInt");
41+
const result = [];
42+
while (value >= 0x80) {
43+
result.push(Number(value & BigInt(0x7f)) | 0x80);
44+
value >>= BigInt(7);
45+
}
46+
result.push(Number(value));
47+
return result;
48+
} else {
49+
return Protobuf.varIntEncode(Number(input));
50+
}
3951
} catch (err) {
4052
throw new OperationError(err);
4153
}

0 commit comments

Comments
 (0)