Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit d932bbc

Browse files
committed
add preferFloat32: boolean option to encode()
1 parent c4a1ef5 commit d932bbc

3 files changed

Lines changed: 47 additions & 5 deletions

File tree

src/Encoder.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export class Encoder {
1818
readonly maxDepth = DEFAULT_MAX_DEPTH,
1919
readonly initialBufferSize = DEFAULT_INITIAL_BUFFER_SIZE,
2020
readonly sortKeys = false,
21+
readonly preferFloat32 = false,
2122
) {}
2223

2324
encode(object: unknown, depth: number): void {
@@ -118,8 +119,16 @@ export class Encoder {
118119
}
119120
}
120121
} else {
121-
this.writeU8(0xcb);
122-
this.writeF64(object);
122+
// non-integer numbers
123+
if (this.preferFloat32) {
124+
// float 32
125+
this.writeU8(0xca);
126+
this.writeF32(object);
127+
} else {
128+
// float 64
129+
this.writeU8(0xcb);
130+
this.writeF64(object);
131+
}
123132
}
124133
}
125134

@@ -345,9 +354,14 @@ export class Encoder {
345354
this.pos += 4;
346355
}
347356

357+
writeF32(value: number) {
358+
this.ensureBufferSizeToWrite(4);
359+
this.view.setFloat32(this.pos, value);
360+
this.pos += 4;
361+
}
362+
348363
writeF64(value: number) {
349364
this.ensureBufferSizeToWrite(8);
350-
351365
this.view.setFloat64(this.pos, value);
352366
this.pos += 8;
353367
}

src/encode.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ export type EncodeOptions = Partial<
77
maxDepth: number;
88
initialBufferSize: number;
99
sortKeys: boolean;
10+
11+
/**
12+
* If `true`, float32 is preferred in encoding non-integer numbers, insted of float64.
13+
*/
14+
preferFloat32: boolean;
1015
}>
1116
>;
1217

@@ -19,7 +24,13 @@ const defaultEncodeOptions = {};
1924
* The returned buffer is a slice of a larger `ArrayBuffer`, so you have to use its `#byteOffset` and `#byteLength` in order to convert it to another typed arrays including NodeJS `Buffer`.
2025
*/
2126
export function encode(value: unknown, options: EncodeOptions = defaultEncodeOptions): Uint8Array {
22-
const encoder = new Encoder(options.extensionCodec, options.maxDepth, options.initialBufferSize, options.sortKeys);
27+
const encoder = new Encoder(
28+
options.extensionCodec,
29+
options.maxDepth,
30+
options.initialBufferSize,
31+
options.sortKeys,
32+
options.preferFloat32,
33+
);
2334
encoder.encode(value, 1);
2435
return encoder.getUint8Array();
2536
}

test/encode.test.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,28 @@ import { encode, decode } from "@msgpack/msgpack";
33

44
describe("encode", () => {
55
context("sortKeys", () => {
6-
it("canonicalize encoded binaries", () => {
6+
it("canonicalizes encoded binaries", () => {
77
assert.deepStrictEqual(encode({ a: 1, b: 2 }, { sortKeys: true }), encode({ b: 2, a: 1 }, { sortKeys: true }));
88
});
99
});
1010

11+
context("preferFloat32", () => {
12+
it("encodes numbers in float64 wihout preferFloat32", () => {
13+
assert.deepStrictEqual(encode(3.14), Uint8Array.from([0xcb, 0x40, 0x9, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f]));
14+
});
15+
16+
it("encodes numbers in float32 when preferFloate32=true", () => {
17+
assert.deepStrictEqual(encode(3.14, { preferFloat32: true }), Uint8Array.from([0xca, 0x40, 0x48, 0xf5, 0xc3]));
18+
});
19+
20+
it("encodes numbers in float64 with preferFloat32=false", () => {
21+
assert.deepStrictEqual(
22+
encode(3.14, { preferFloat32: false }),
23+
Uint8Array.from([0xcb, 0x40, 0x9, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f]),
24+
);
25+
});
26+
});
27+
1128
context("ArrayBuffer as buffer", () => {
1229
const buffer = encode([1, 2, 3]);
1330
const arrayBuffer = buffer.buffer.slice(buffer.byteOffset, buffer.byteLength);

0 commit comments

Comments
 (0)