Skip to content

Commit 9050c93

Browse files
committed
fix #212
1 parent 9b4123a commit 9050c93

File tree

4 files changed

+64
-7
lines changed

4 files changed

+64
-7
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# This is the revision history of @msgpack/msgpack
22

3+
## NEXT
4+
5+
* Let `Encoder#encode()` return a copy of the internal buffer, instead of the reference of the buffer (fix #212).
6+
* Introducing `Encoder#encodeSharedRef()` to return the shared reference to the internal buffer.
7+
38
## 2.7.2 2022/02/08
49

510
https://github.com/msgpack/msgpack-javascript/compare/v2.7.1...v2.7.2

src/Encoder.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,28 @@ export class Encoder<ContextType = undefined> {
2323
private readonly forceIntegerToFloat = false,
2424
) {}
2525

26-
private getUint8Array(): Uint8Array {
27-
return this.bytes.subarray(0, this.pos);
28-
}
29-
3026
private reinitializeState() {
3127
this.pos = 0;
3228
}
3329

30+
/**
31+
* This is almost equivalent to {@link Encoder#encode}, but it returns an reference of the encoder's internal buffer and thus much faster than {@link Encoder#encode}.
32+
*
33+
* @returns Encodes the object and returns a shared reference the encoder's internal buffer.
34+
*/
35+
public encodeSharedRef(object: unknown): Uint8Array {
36+
this.reinitializeState();
37+
this.doEncode(object, 1);
38+
return this.bytes.subarray(0, this.pos);
39+
}
40+
41+
/**
42+
* @returns Encodes the object and returns a copy of the encoder's internal buffer.
43+
*/
3444
public encode(object: unknown): Uint8Array {
3545
this.reinitializeState();
3646
this.doEncode(object, 1);
37-
return this.getUint8Array();
47+
return this.bytes.slice(0, this.pos);
3848
}
3949

4050
private doEncode(object: unknown, depth: number): void {

src/encode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,5 @@ export function encode<ContextType = undefined>(
7777
options.ignoreUndefined,
7878
options.forceIntegerToFloat,
7979
);
80-
return encoder.encode(value);
80+
return encoder.encodeSharedRef(value);
8181
}

test/reuse-instances.test.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { deepStrictEqual } from "assert";
2-
import { Encoder, Decoder } from "@msgpack/msgpack";
2+
import { Encoder, Decoder, decode } from "@msgpack/msgpack";
33

44
const createStream = async function* (...args: any) {
55
for (const item of args) {
@@ -108,5 +108,47 @@ describe("shared instances", () => {
108108
deepStrictEqual(a, [[object]], `#${i}`);
109109
}
110110
});
111+
112+
context("regression #212", () => {
113+
it("runs multiple times", () => {
114+
const encoder = new Encoder();
115+
const decoder = new Decoder();
116+
117+
const data1 = {
118+
isCommunication: false,
119+
isWarning: false,
120+
alarmId: "619f65a2774abf00568b7210",
121+
intervalStart: "2022-05-20T12:00:00.000Z",
122+
intervalStop: "2022-05-20T13:00:00.000Z",
123+
triggeredAt: "2022-05-20T13:00:00.000Z",
124+
component: "someComponent",
125+
_id: "6287920245a582301475627d",
126+
};
127+
128+
const data2 = {
129+
foo: "bar",
130+
};
131+
132+
const arr = [data1, data2];
133+
const enc = arr.map((x) => [x, encoder.encode(x)] as const);
134+
135+
enc.forEach(([orig, acc]) => {
136+
const des = decoder.decode(acc);
137+
deepStrictEqual(des, orig);
138+
});
139+
});
140+
});
141+
142+
context("Encoder#encodeSharedRef()", () => {
143+
it("returns the shared reference", () => {
144+
const encoder = new Encoder();
145+
146+
const a = encoder.encodeSharedRef(true);
147+
const b = encoder.encodeSharedRef(false);
148+
149+
deepStrictEqual(decode(a), decode(b)); // yes, this is the expected behavior
150+
deepStrictEqual(a.buffer, b.buffer);
151+
});
152+
});
111153
});
112154
});

0 commit comments

Comments
 (0)