Skip to content

Commit 6039e48

Browse files
committed
Review feedback
BREAKING CHANGE: `useBigInt64` deprecated from Encoder and > 32 bit ints now get encoded as a uint64 rather than float64
1 parent eeeec65 commit 6039e48

File tree

4 files changed

+25
-35
lines changed

4 files changed

+25
-35
lines changed

README.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ console.log(buffer);
114114
| ------------------- | -------------- | ----------------------------- |
115115
| extensionCodec | ExtensionCodec | `ExtensionCodec.defaultCodec` |
116116
| context | user-defined | - |
117-
| useInt64 | boolean | false |
118117
| forceBigIntToInt64 | boolean | false |
119118
| maxDepth | number | `100` |
120119
| initialBufferSize | number | `2048` |
@@ -381,9 +380,9 @@ This library does not handle decoding BigInt by default, but you have three opti
381380

382381
**Encoding**
383382

384-
This library will encode a BigInt into a MessagePack int64/uint64 if it is > 32-bit OR you set `forceBigIntToInt64` to `true`. This library will encode a `number` that is > 32-bit into a MessagePack int64/uint64 if it is > 32-bit ONLY if you set `useInt64` to true, otherwise it encodes it as a MessagePack float64.
383+
This library will encode a BigInt into a MessagePack int64/uint64 if it is > 32-bit OR you set `forceBigIntToInt64` to `true`. This library will encode a `number` that is > 32-bit into a MessagePack int64/uint64 if it is > 32-bit.
385384

386-
If you set `forceBigIntToInt64` to `true` the note:
385+
If you set `forceBigIntToInt64` to `true` note:
387386

388387
- A bigint is encoded in 8 byte binaries even if it's a small integer
389388
- A bigint must be smaller than the max value of the uint64 and larger than the min value of the int64. Otherwise the behavior is undefined.

src/Decoder.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ export class Decoder<ContextType = undefined> {
221221
this.extensionCodec = options?.extensionCodec ?? (ExtensionCodec.defaultCodec as ExtensionCodecType<ContextType>);
222222
this.context = (options as { context: ContextType } | undefined)?.context as ContextType; // needs a type assertion because EncoderOptions has no context property when ContextType is undefined
223223

224-
this.intMode = options?.intMode ?? options?.useBigInt64 ? IntMode.AS_ENCODED : IntMode.UNSAFE_NUMBER;
224+
this.intMode = options?.intMode ?? (options?.useBigInt64 ? IntMode.AS_ENCODED : IntMode.UNSAFE_NUMBER);
225225
this.maxStrLength = options?.maxStrLength ?? UINT32_MAX;
226226
this.maxBinLength = options?.maxBinLength ?? UINT32_MAX;
227227
this.maxArrayLength = options?.maxArrayLength ?? UINT32_MAX;

src/Encoder.ts

+8-28
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { utf8Count, utf8Encode } from "./utils/utf8";
22
import { ExtensionCodec, ExtensionCodecType } from "./ExtensionCodec";
3+
import { setInt64, setUint64 } from "./utils/int";
34
import { ensureUint8Array } from "./utils/typedArrays";
45
import type { ExtData } from "./ExtData";
56
import type { ContextOf } from "./context";
6-
import { setInt64, setUint64 } from "./utils/int";
77

88
export const DEFAULT_MAX_DEPTH = 100;
99
export const DEFAULT_INITIAL_BUFFER_SIZE = 2048;
@@ -12,13 +12,6 @@ export type EncoderOptions<ContextType = undefined> = Partial<
1212
Readonly<{
1313
extensionCodec: ExtensionCodecType<ContextType>;
1414

15-
/**
16-
* Encodes a `number` greater than 32-bit as Int64 or Uint64 if it's set to true, otherwise encode as float64.
17-
*
18-
* Defaults to false.
19-
*/
20-
useInt64: boolean;
21-
2215
/**
2316
* Encodes bigint as Int64 or Uint64 if it's set to true, regardless of the size of bigint number.
2417
* {@link forceIntegerToFloat} does not affect bigint.
@@ -29,9 +22,6 @@ export type EncoderOptions<ContextType = undefined> = Partial<
2922
*/
3023
forceBigIntToInt64: boolean;
3124

32-
/** @deprecated Alias of `forceBigIntToInt64` */
33-
useBigInt64: boolean;
34-
3525
/**
3626
* The maximum depth in nested objects and arrays.
3727
*
@@ -86,7 +76,6 @@ export class Encoder<ContextType = undefined> {
8676
private readonly extensionCodec: ExtensionCodecType<ContextType>;
8777
private readonly context: ContextType;
8878
private readonly forceBigIntToInt64: boolean;
89-
private readonly useInt64: boolean;
9079
private readonly maxDepth: number;
9180
private readonly initialBufferSize: number;
9281
private readonly sortKeys: boolean;
@@ -102,8 +91,7 @@ export class Encoder<ContextType = undefined> {
10291
this.extensionCodec = options?.extensionCodec ?? (ExtensionCodec.defaultCodec as ExtensionCodecType<ContextType>);
10392
this.context = (options as { context: ContextType } | undefined)?.context as ContextType; // needs a type assertion because EncoderOptions has no context property when ContextType is undefined
10493

105-
this.forceBigIntToInt64 = options?.forceBigIntToInt64 ?? options?.useBigInt64 ?? false;
106-
this.useInt64 = options?.useInt64 ?? false;
94+
this.forceBigIntToInt64 = options?.forceBigIntToInt64 ?? false;
10795
this.maxDepth = options?.maxDepth ?? DEFAULT_MAX_DEPTH;
10896
this.initialBufferSize = options?.initialBufferSize ?? DEFAULT_INITIAL_BUFFER_SIZE;
10997
this.sortKeys = options?.sortKeys ?? false;
@@ -150,15 +138,9 @@ export class Encoder<ContextType = undefined> {
150138
} else if (typeof object === "boolean") {
151139
this.encodeBoolean(object);
152140
} else if (typeof object === "number") {
153-
if (!this.forceIntegerToFloat) {
154-
this.encodeNumber(object);
155-
} else {
156-
this.encodeNumberAsFloat(object);
157-
}
141+
this.encodeNumber(object);
158142
} else if (typeof object === "string") {
159143
this.encodeString(object);
160-
} else if (this.forceBigIntToInt64 && typeof object === "bigint") {
161-
this.encodeBigIntAsInt64(object);
162144
} else {
163145
this.encodeObject(object, depth);
164146
}
@@ -213,12 +195,10 @@ export class Encoder<ContextType = undefined> {
213195
// uint 32
214196
this.writeU8(0xce);
215197
this.writeU32(object);
216-
} else if (this.useInt64) {
198+
} else {
217199
// uint 64
218200
this.writeU8(0xcf);
219201
this.writeU64(object);
220-
} else {
221-
this.encodeNumberAsFloat(object);
222202
}
223203
} else {
224204
if (object >= -0x20) {
@@ -236,12 +216,10 @@ export class Encoder<ContextType = undefined> {
236216
// int 32
237217
this.writeU8(0xd2);
238218
this.writeI32(object);
239-
} else if (this.useInt64) {
219+
} else {
240220
// int 64
241221
this.writeU8(0xd3);
242222
this.writeI64(object);
243-
} else {
244-
this.encodeNumberAsFloat(object);
245223
}
246224
}
247225
} else {
@@ -262,7 +240,9 @@ export class Encoder<ContextType = undefined> {
262240
}
263241

264242
private encodeBigInt(object: bigint) {
265-
if (object >= 0) {
243+
if (this.forceBigIntToInt64) {
244+
this.encodeBigIntAsInt64(object);
245+
} else if (object >= 0) {
266246
if (object < 0x100000000 || this.forceIntegerToFloat) {
267247
// uint 32 or lower, or force to float
268248
this.encodeNumber(Number(object));

test/bigint64.test.ts

+14-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import assert from "assert";
22
import { encode, decode, IntMode, ExtensionCodec, DecodeError } from "../src";
3-
import { getInt64, getUint64 } from "src/utils/int";
3+
import { getInt64, getUint64 } from "../src/utils/int";
44

55
describe("useBigInt64: true", () => {
66
before(function () {
@@ -27,14 +27,25 @@ describe("useBigInt64: true", () => {
2727
assert.deepStrictEqual(decode(encoded, { useBigInt64: true }), value);
2828
});
2929

30-
it("encodes and decodes values with numbers and bigints", () => {
30+
it("encodes and decodes values with numbers and bigints - MIXED", () => {
3131
const value = {
3232
ints: [0, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER],
3333
nums: [Number.NaN, Math.PI, Math.E, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY],
34+
bigints: [BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1), BigInt(Number.MIN_SAFE_INTEGER) - BigInt(1)],
35+
};
36+
const encoded = encode(value, { forceBigIntToInt64: true });
37+
const decoded = decode(encoded, { intMode: IntMode.MIXED });
38+
assert.deepStrictEqual(decoded, value);
39+
});
40+
41+
it("encodes and decodes values with numbers and bigints - AS_ENCODED", () => {
42+
const value = {
43+
ints: [0, Math.pow(2, 32) - 1, -1 * Math.pow(2, 31)],
44+
nums: [Number.NaN, Math.PI, Math.E, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY],
3445
bigints: [BigInt(0), BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1), BigInt(Number.MIN_SAFE_INTEGER) - BigInt(1)],
3546
};
3647
const encoded = encode(value, { forceBigIntToInt64: true });
37-
const decoded = decode(encoded, { useBigInt64: true });
48+
const decoded = decode(encoded, { intMode: IntMode.AS_ENCODED });
3849
assert.deepStrictEqual(decoded, value);
3950
});
4051
});

0 commit comments

Comments
 (0)