Skip to content

Commit b409b67

Browse files
0.3.1
1 parent 810800e commit b409b67

File tree

9 files changed

+70
-24
lines changed

9 files changed

+70
-24
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
[![codecov](https://codecov.io/gh/username0101010/array-buffer-serializer/branch/main/graph/badge.svg?token=IZFQQP34H7)](https://codecov.io/gh/username0101010/array-buffer-serializer)
55

66
Allows to encode an object into bytes before transmission via WebRTC or WebSocket and decode it back when received.
7+
This is very useful for network bandwidth when you need to send data to one or more recipients frequently.
78

8-
Some characters of the [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)), which is part of
9-
[Unicode](https://en.wikipedia.org/wiki/Unicode), are reserved for encoding values: C0 (U+00C0) - E3 (U+00E3).
9+
Some characters of the [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block))
10+
are reserved for encoding values: C0 (U+00C0) - E3 (U+00E7).
1011

1112
## Installation
1213

@@ -45,7 +46,7 @@ yarn add array-buffer-serializer
4546
```
4647

4748
3. **Send the buffer (for example, over WebScoket)**
48-
49+
frequently
4950
```javascript
5051
ws.send(buffer);
5152
```
@@ -80,7 +81,7 @@ Type | Economy (bytes)
8081
* Uses type definition instead of object's key-value separator ":" and array items delimiter ",";
8182
* Uses unsigned data representation by default (uint8_t, uint16_t...);
8283
* Different marks for positive and negative numbers, so negative sign is for free;
83-
* Marks are divided into even and odd, each odd mark indicates at the first array value, which saves at least 1 byte.
84+
* Marks are divided into even and odd, each odd mark indicates at the first array value.
8485
8586
## License
8687

example/object.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,8 @@ const data = {
3636
}
3737
};
3838

39-
// NOTE: JSON.stringify() can't convert bigint
40-
// just to show length of all data, it was converted to a string
41-
const temp = { ...data };
42-
temp.bigint = data.bigint.toString();
43-
console.log("Original length:", JSON.stringify(temp).length - 1); // 451
39+
BigInt.prototype.toJSON = function() { return this.toString() };
40+
console.log("Original length:", JSON.stringify(data).length - 1); // 451
4441

4542
const buffer = Serializer.toBuffer(data);
4643
console.log("Encoded length:", buffer.byteLength); // 249

lib/BufferDecoder.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ BufferDecoder.prototype.decode = function() {
4040
return;
4141
}
4242

43-
else if (0x00C0 <= code && code <= 0x00DF) {
43+
else if (0x00C0 <= code && code <= 0x00E3) {
4444
this._parseValue(code - (code % 2 === 1 ? 1 : 0));
4545

4646
// parse value as 1st array element
@@ -127,11 +127,19 @@ BufferDecoder.prototype._parseValue = function(code) {
127127

128128
// -uint64_t
129129
else if (code === marks.DEFAULT_MARK_INT64)
130-
this._value = -(this._fromInt64());
130+
this._value = -(Number(this._fromInt64()));
131131

132132
// uint64_t
133133
else if (code === marks.DEFAULT_MARK_UINT64)
134-
this._value = this._fromInt64();
134+
this._value = Number(this._fromInt64());
135+
136+
// -bigint
137+
else if (code === marks.DEFAULT_MARK_BIGINT)
138+
this._value = -(this._fromInt64());
139+
140+
// bigint
141+
else if (code === marks.DEFAULT_MARK_UBIGINT)
142+
this._value = this._fromInt64();
135143

136144
// float
137145
else if (code === marks.DEFAULT_MARK_FLOAT)

lib/BufferEncoder.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ BufferEncoder.prototype.encode = function(key, val, index) {
7171
this._setMark(marks.DEFAULT_MARK_UNDEF, index);
7272
break;
7373
case "bigint":
74-
this._setMark(val < 0 ? marks.DEFAULT_MARK_INT64 : marks.DEFAULT_MARK_UINT64, index);
74+
this._setMark(val < 0 ? marks.DEFAULT_MARK_BIGINT : marks.DEFAULT_MARK_UBIGINT, index);
7575
this._toInt64(val < 0 ? -val : val);
7676
break;
7777
case "number":
@@ -149,6 +149,12 @@ BufferEncoder.prototype._asInteger = function(val, index) {
149149
this._setMark(val < 0 ? marks.DEFAULT_MARK_INT32 : marks.DEFAULT_MARK_UINT32, index);
150150
this._toInt32(absVal);
151151
}
152+
153+
// uint64_t
154+
else if (absVal <= 18446744073709552000) {
155+
this._setMark(val < 0 ? marks.DEFAULT_MARK_INT64 : marks.DEFAULT_MARK_UINT64, index);
156+
this._toInt64(val < 0 ? BigInt(-val) : BigInt(val));
157+
}
152158
};
153159

154160
/**

lib/marks.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,34 +113,50 @@ module.exports = {
113113
* @default
114114
*/
115115
DEFAULT_MARK_OBJ_OPEN: 0x00DE,
116+
/**
117+
* Mark for unsigned bigint.
118+
*
119+
* @example 25n
120+
* @constant
121+
* @default
122+
*/
123+
DEFAULT_MARK_UBIGINT: 0x00E0,
124+
/**
125+
* Mark for signed bigint.
126+
*
127+
* @example -25n
128+
* @constant
129+
* @default
130+
*/
131+
DEFAULT_MARK_BIGINT: 0x00E2,
116132
/**
117133
* Mark for close object value.
118134
*
119135
* @example }
120136
* @constant
121137
* @default
122138
*/
123-
DEFAULT_MARK_OBJ_CLOSE: 0x00E0,
139+
DEFAULT_MARK_OBJ_CLOSE: 0x00E4,
124140
/**
125141
* Mark for close array value.
126142
*
127143
* @example ]
128144
* @constant
129145
* @default
130146
*/
131-
DEFAULT_MARK_ARR_CLOSE: 0x00E1,
147+
DEFAULT_MARK_ARR_CLOSE: 0x00E5,
132148
/** Mark for open array value.
133149
*
134150
* @example [
135151
* @constant
136152
* @default
137153
*/
138-
DEFAULT_MARK_ARR_OPEN: 0x00E2,
154+
DEFAULT_MARK_ARR_OPEN: 0x00E6,
139155
/** Mark for empty array value.
140156
*
141157
* @example []
142158
* @constant
143159
* @default
144160
*/
145-
DEFAULT_MARK_ARR_EMPTY: 0x00E3
161+
DEFAULT_MARK_ARR_EMPTY: 0x00E7
146162
};

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "array-buffer-serializer",
3-
"version": "0.3.0",
3+
"version": "0.3.1",
44
"description": "Serializes data to transfer fewer bytes over the network",
55
"main": "index.js",
66
"types": "index.d.ts",

test/BufferDecoder.test.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ describe("BufferDecoder", () => {
1616
const setNegAndPosIntAtOnce = exp => {
1717
let offset = exp / 8;
1818
let method = exp < 64 ? `setUint${exp}` : `setBigUint${exp}`;
19-
let number = exp < 64 ? Math.pow(2, exp) - 1 : 2n ** 64n - 1n;
19+
let number = exp < 64 ? Math.pow(2, exp) - 1 : BigInt(Math.pow(2, 42));
2020

2121
// set positive
2222
dv.setUint8(1, marks[`DEFAULT_MARK_UINT${exp}`]);
2323
dv[method](2, number);
2424
// set negative
2525
dv.setUint8(2 + offset, marks[`DEFAULT_MARK_INT${exp}`]);
2626
dv[method](3 + offset, number);
27-
decodeAndExpect(1 + offset, number, 0, [0]);
28-
decodeAndExpect((1 + offset) * 2, -number, 1, [1]);
27+
decodeAndExpect(1 + offset, exp < 64 ? number : Number(number), 0, [0]);
28+
decodeAndExpect((1 + offset) * 2, exp < 64 ? -number : -(Number(number)), 1, [1]);
2929
};
3030

3131
beforeEach(() => {
@@ -65,6 +65,18 @@ describe("BufferDecoder", () => {
6565
decodeAndExpect(9, 1.23456789012, 0);
6666
});
6767

68+
it("decodes bigint correctly", () => {
69+
dv.setUint8(1, marks.DEFAULT_MARK_BIGINT);
70+
dv.setBigUint64(2, 2n);
71+
decodeAndExpect(9, -2n, 0);
72+
});
73+
74+
it("decodes ubigint correctly", () => {
75+
dv.setUint8(1, marks.DEFAULT_MARK_UBIGINT);
76+
dv.setBigUint64(2, 2n);
77+
decodeAndExpect(9, 2n, 0);
78+
});
79+
6880
it("decodes boolean (both: true and false) correctly", () => {
6981
dv.setUint8(1, marks.DEFAULT_MARK_FBOOL);
7082
dv.setUint8(2, marks.DEFAULT_MARK_TBOOL);

test/BufferEncoder.test.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ describe("BufferEncoder", () => {
2222
expect(bufferEncoder._bytes).toBe(4);
2323
});
2424

25-
it("encodes to uint64 correctly", () => {
25+
it("encodes to ubigint correctly", () => {
2626
bufferEncoder._toInt64(2n ** 64n - 1n);
2727
expect(bufferEncoder._bytes).toBe(8);
2828
});
@@ -102,12 +102,18 @@ describe("BufferEncoder", () => {
102102
expect(bufferEncoder._bytes).toBe(10);
103103
});
104104

105-
it("encodes 2^64 and -2^64 as 18 bytes (with marks)", () => {
105+
it("encodes 2^64 and -2^64 (bigint) as 18 bytes (with marks)", () => {
106106
bufferEncoder.encode(undefined, 2n ** 64n - 1n);
107107
bufferEncoder.encode(undefined, -(2n ** 64n - 1n));
108108
expect(bufferEncoder._bytes).toBe(18);
109109
});
110110

111+
it("encodes 2^64 and -2^64 (integer) as 18 bytes (with marks)", () => {
112+
bufferEncoder.encode(undefined, 2 ** 64 - 1);
113+
bufferEncoder.encode(undefined, -(2 ** 64 - 1));
114+
expect(bufferEncoder._bytes).toBe(18);
115+
});
116+
111117
it("encodes 1.234567 as 5 bytes (float with mark)", () => {
112118
bufferEncoder.encode(undefined, 1.234567);
113119
expect(bufferEncoder._bytes).toBe(5);

0 commit comments

Comments
 (0)