Skip to content

Commit 153def4

Browse files
authored
Merge pull request #231 from runk/greg/bigints
feat: uint64 and uint128 now decode to BigInts
2 parents ae84e9e + a109747 commit 153def4

File tree

4 files changed

+30
-49
lines changed

4 files changed

+30
-49
lines changed

src/__test__/integration.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@ describe('mmdb lib', () => {
9090
float: 0,
9191
int32: 0,
9292
map: {},
93-
uint128: 0,
93+
uint128: 0n,
9494
uint16: 0,
9595
uint32: 0,
96-
uint64: 0,
96+
uint64: 0n,
9797
utf8_string: '',
9898
},
9999
},
@@ -116,10 +116,10 @@ describe('section: data', () => {
116116
float: 1.100000023841858,
117117
int32: -268435456,
118118
map: { mapX: { arrayX: [7, 8, 9], utf8_stringX: 'hello' } },
119-
uint128: '1329227995784915872903807060280344576',
119+
uint128: 1329227995784915872903807060280344576n,
120120
uint16: 100,
121121
uint32: 268435456,
122-
uint64: '1152921504606846976',
122+
uint64: 1152921504606846976n,
123123
utf8_string: 'unicode! ☯ - ♫',
124124
});
125125
});
@@ -134,10 +134,10 @@ describe('section: data', () => {
134134
float: 0,
135135
int32: 0,
136136
map: {},
137-
uint128: 0,
137+
uint128: 0n,
138138
uint16: 0,
139139
uint32: 0,
140-
uint64: 0,
140+
uint64: 0n,
141141
utf8_string: '',
142142
});
143143
});
@@ -217,10 +217,10 @@ describe('getWithPrefixLength', () => {
217217
utf8_stringX: 'hello',
218218
},
219219
},
220-
uint128: '1329227995784915872903807060280344576',
220+
uint128: 1329227995784915872903807060280344576n,
221221
uint16: 0x64,
222222
uint32: 268435456,
223-
uint64: '1152921504606846976',
223+
uint64: 1152921504606846976n,
224224
utf8_string: 'unicode! ☯ - ♫',
225225
};
226226
const tests = [

src/decoder.test.ts

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import { strict as assert } from 'assert';
2-
import fs from 'fs';
3-
import path from 'path';
42
import Decoder from './decoder';
53

64
describe('lib/decoder', () => {
@@ -14,19 +12,6 @@ describe('lib/decoder', () => {
1412
});
1513
});
1614

17-
describe('decodeUint()', () => {
18-
it('should return zero for unsupported int size', () => {
19-
const decoder: any = new Decoder(
20-
fs.readFileSync(
21-
path.join(__dirname, '../test/data/test-data/GeoIP2-City-Test.mmdb')
22-
),
23-
1
24-
);
25-
26-
assert.strictEqual(decoder.decodeUint(1, 32), 0);
27-
});
28-
});
29-
3015
describe('decodeArray()', () => {
3116
const testCases = [
3217
{
@@ -407,20 +392,17 @@ describe('lib/decoder', () => {
407392

408393
function generateLargeUintCases(
409394
bits: 64 | 128
410-
): { expected: number | string; input: number[] }[] {
395+
): { expected: bigint; input: number[] }[] {
411396
const ctrlByte = bits === 64 ? 0x02 : 0x03;
412-
const cases: { expected: number | string; input: number[] }[] = [];
413-
414-
cases.push({ expected: 0, input: [0x00, ctrlByte] });
415-
cases.push({ expected: 500, input: [0x02, ctrlByte, 0x01, 0xf4] });
416-
cases.push({ expected: 10872, input: [0x02, ctrlByte, 0x2a, 0x78] });
397+
const cases = [
398+
{ expected: 0n, input: [0x00, ctrlByte] },
399+
{ expected: 500n, input: [0x02, ctrlByte, 0x01, 0xf4] },
400+
{ expected: 10872n, input: [0x02, ctrlByte, 0x2a, 0x78] },
401+
];
417402

418403
const maxBytes = bits / 8;
419404
for (let byteCount = 1; byteCount <= maxBytes; byteCount++) {
420-
const expectedNum = (1n << BigInt(8 * byteCount)) - 1n;
421-
// For some reason we convert big ints to strings in the decoder
422-
const expectedValue =
423-
byteCount <= 6 ? Number(expectedNum) : expectedNum.toString();
405+
const expectedValue = (1n << BigInt(8 * byteCount)) - 1n;
424406

425407
const inputBytes: number[] = Array(byteCount).fill(0xff);
426408
const input = [byteCount, ctrlByte, ...inputBytes];
@@ -429,7 +411,7 @@ describe('lib/decoder', () => {
429411
return cases;
430412
}
431413

432-
describe('decodeUint() - uint64', () => {
414+
describe('decodeBigUint() - uint64', () => {
433415
const testCases = generateLargeUintCases(64);
434416

435417
for (const tc of testCases) {
@@ -441,7 +423,7 @@ describe('lib/decoder', () => {
441423
}
442424
});
443425

444-
describe('decodeUint() - uint128', () => {
426+
describe('decodeBigUint() - uint128', () => {
445427
const testCases = generateLargeUintCases(128);
446428

447429
for (const tc of testCases) {

src/decoder.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@ export default class Decoder {
123123
case DataType.Int32:
124124
return cursor(this.decodeInt32(offset, size), newOffset);
125125
case DataType.Uint64:
126-
return cursor(this.decodeUint(offset, size), newOffset);
126+
return cursor(this.decodeBigUint(offset, size), newOffset);
127127
case DataType.Uint128:
128-
return cursor(this.decodeUint(offset, size), newOffset);
128+
return cursor(this.decodeBigUint(offset, size), newOffset);
129129
}
130130

131131
throw new Error('Unknown type ' + type + ' at offset ' + offset);
@@ -269,32 +269,31 @@ export default class Decoder {
269269
return this.db.readInt32BE(offset);
270270
}
271271

272-
private decodeUint(offset: number, size: number) {
272+
private decodeUint(offset: number, size: number): number {
273273
if (size === 0) {
274274
return 0;
275275
}
276-
if (size <= 6) {
276+
if (size <= 4) {
277277
return this.db.readUIntBE(offset, size);
278278
}
279-
if (size == 8) {
280-
return this.db.readBigUInt64BE(offset).toString();
281-
}
282-
if (size > 16) {
283-
return 0;
284-
}
285-
return this.decodeBigUint(offset, size);
279+
280+
throw new Error(`Invalid size for unsigned integer: ${size}`);
286281
}
287282

288283
private decodeString(offset: number, size: number) {
289284
return this.db.toString('utf8', offset, offset + size);
290285
}
291286

292-
private decodeBigUint(offset: number, size: number) {
287+
private decodeBigUint(offset: number, size: number): bigint {
288+
if (size > 16) {
289+
throw new Error(`Invalid size for big unsigned integer: ${size}`);
290+
}
291+
293292
let integer = 0n;
294293
for (let i = 0; i < size; i++) {
295294
integer <<= 8n;
296295
integer |= BigInt(this.db.readUInt8(offset + i));
297296
}
298-
return integer.toString();
297+
return integer;
299298
}
300299
}

src/metadata.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export const parseMetadata = (db: Buffer): Metadata => {
4242
return {
4343
binaryFormatMajorVersion: metadata.binary_format_major_version,
4444
binaryFormatMinorVersion: metadata.binary_format_minor_version,
45-
buildEpoch: new Date(metadata.build_epoch * 1000),
45+
buildEpoch: new Date(Number(metadata.build_epoch) * 1000),
4646
databaseType: metadata.database_type,
4747
description: metadata.description,
4848
ipVersion: metadata.ip_version,

0 commit comments

Comments
 (0)