microcbor 0.3.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +173 -56
- package/lib/CBORDecoderStream.d.ts +5 -0
- package/lib/CBORDecoderStream.js +37 -0
- package/lib/CBOREncoderStream.d.ts +9 -0
- package/lib/CBOREncoderStream.js +24 -0
- package/lib/{decode.d.ts → Decoder.d.ts} +1 -0
- package/lib/{decode.js → Decoder.js} +1 -0
- package/lib/Encoder.d.ts +65 -0
- package/lib/Encoder.js +291 -0
- package/lib/decodeAsyncIterable.d.ts +37 -0
- package/lib/{decodeStream.js → decodeAsyncIterable.js} +11 -4
- package/lib/decodeIterable.d.ts +3 -0
- package/lib/decodeIterable.js +206 -0
- package/lib/encodeAsyncIterable.d.ts +4 -0
- package/lib/encodeAsyncIterable.js +9 -0
- package/lib/encodeIterable.d.ts +4 -0
- package/lib/encodeIterable.js +9 -0
- package/lib/encodingLength.d.ts +5 -1
- package/lib/encodingLength.js +8 -66
- package/lib/index.d.ts +8 -4
- package/lib/index.js +8 -4
- package/lib/utils.d.ts +7 -0
- package/lib/utils.js +72 -0
- package/package.json +16 -9
- package/lib/decodeStream.d.ts +0 -2
- package/lib/encode.d.ts +0 -35
- package/lib/encode.js +0 -228
- package/lib/encodeStream.d.ts +0 -4
- package/lib/encodeStream.js +0 -8
package/lib/encodingLength.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import { getFloat16Precision, getFloat32Precision
|
|
1
|
+
import { Precision, getFloat16Precision, getFloat32Precision } from "fp16";
|
|
2
|
+
import { getByteLength } from "./utils.js";
|
|
3
|
+
/**
|
|
4
|
+
* Calculate the byte length that a value will encode into
|
|
5
|
+
* without actually allocating anything.
|
|
6
|
+
*/
|
|
2
7
|
export function encodingLength(value) {
|
|
3
8
|
if (value === false) {
|
|
4
9
|
return 1;
|
|
@@ -70,9 +75,7 @@ function numberEncodingLength(value) {
|
|
|
70
75
|
else if (Object.is(value, -0)) {
|
|
71
76
|
return floatEncodingLength(value);
|
|
72
77
|
}
|
|
73
|
-
else if (Math.floor(value) === value &&
|
|
74
|
-
Number.MIN_SAFE_INTEGER <= value &&
|
|
75
|
-
value <= Number.MAX_SAFE_INTEGER) {
|
|
78
|
+
else if (Math.floor(value) === value && Number.MIN_SAFE_INTEGER <= value && value <= Number.MAX_SAFE_INTEGER) {
|
|
76
79
|
return integerEncodingLength(value);
|
|
77
80
|
}
|
|
78
81
|
else {
|
|
@@ -99,71 +102,10 @@ function floatEncodingLength(value) {
|
|
|
99
102
|
}
|
|
100
103
|
}
|
|
101
104
|
function stringEncodingLength(value) {
|
|
102
|
-
const length =
|
|
105
|
+
const length = getByteLength(value);
|
|
103
106
|
return argumentEncodingLength(length) + length;
|
|
104
107
|
}
|
|
105
108
|
function bytesEncodingLength(value) {
|
|
106
109
|
const length = value.byteLength;
|
|
107
110
|
return argumentEncodingLength(length) + length;
|
|
108
111
|
}
|
|
109
|
-
// https://github.com/feross/buffer/blob/57caad4450d241207066ca3832fb8e9095ad402f/index.js#L434
|
|
110
|
-
function byteLength(string) {
|
|
111
|
-
let codePoint;
|
|
112
|
-
const length = string.length;
|
|
113
|
-
let leadSurrogate = null;
|
|
114
|
-
let bytes = 0;
|
|
115
|
-
for (let i = 0; i < length; ++i) {
|
|
116
|
-
codePoint = string.charCodeAt(i);
|
|
117
|
-
// is surrogate component
|
|
118
|
-
if (codePoint > 0xd7ff && codePoint < 0xe000) {
|
|
119
|
-
// last char was a lead
|
|
120
|
-
if (!leadSurrogate) {
|
|
121
|
-
// no lead yet
|
|
122
|
-
if (codePoint > 0xdbff) {
|
|
123
|
-
// unexpected trail
|
|
124
|
-
bytes += 3;
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
else if (i + 1 === length) {
|
|
128
|
-
// unpaired lead
|
|
129
|
-
bytes += 3;
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
// valid lead
|
|
133
|
-
leadSurrogate = codePoint;
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
// 2 leads in a row
|
|
137
|
-
if (codePoint < 0xdc00) {
|
|
138
|
-
bytes += 3;
|
|
139
|
-
leadSurrogate = codePoint;
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
// valid surrogate pair
|
|
143
|
-
codePoint =
|
|
144
|
-
(((leadSurrogate - 0xd800) << 10) | (codePoint - 0xdc00)) + 0x10000;
|
|
145
|
-
}
|
|
146
|
-
else if (leadSurrogate) {
|
|
147
|
-
// valid bmp char, but last char was a lead
|
|
148
|
-
bytes += 3;
|
|
149
|
-
}
|
|
150
|
-
leadSurrogate = null;
|
|
151
|
-
// encode utf8
|
|
152
|
-
if (codePoint < 0x80) {
|
|
153
|
-
bytes += 1;
|
|
154
|
-
}
|
|
155
|
-
else if (codePoint < 0x800) {
|
|
156
|
-
bytes += 2;
|
|
157
|
-
}
|
|
158
|
-
else if (codePoint < 0x10000) {
|
|
159
|
-
bytes += 3;
|
|
160
|
-
}
|
|
161
|
-
else if (codePoint < 0x110000) {
|
|
162
|
-
bytes += 4;
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
throw new Error("Invalid code point");
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return bytes;
|
|
169
|
-
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
export type { CBORValue, CBORMap, CBORArray } from "./types.js";
|
|
2
|
-
export { encode, Encoder } from "./encode.js";
|
|
3
|
-
export { decode, Decoder } from "./decode.js";
|
|
4
|
-
export { encodeStream } from "./encodeStream.js";
|
|
5
|
-
export { decodeStream } from "./decodeStream.js";
|
|
6
2
|
export { encodingLength } from "./encodingLength.js";
|
|
3
|
+
export { Encoder, encode } from "./Encoder.js";
|
|
4
|
+
export { Decoder, decode } from "./Decoder.js";
|
|
5
|
+
export { encodeIterable } from "./encodeIterable.js";
|
|
6
|
+
export { decodeIterable } from "./decodeIterable.js";
|
|
7
|
+
export { encodeAsyncIterable } from "./encodeAsyncIterable.js";
|
|
8
|
+
export { decodeAsyncIterable } from "./decodeAsyncIterable.js";
|
|
9
|
+
export { CBORDecoderStream } from "./CBORDecoderStream.js";
|
|
10
|
+
export { CBOREncoderStream } from "./CBOREncoderStream.js";
|
|
7
11
|
export { UnsafeIntegerError } from "./utils.js";
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
export { encode, Encoder } from "./encode.js";
|
|
2
|
-
export { decode, Decoder } from "./decode.js";
|
|
3
|
-
export { encodeStream } from "./encodeStream.js";
|
|
4
|
-
export { decodeStream } from "./decodeStream.js";
|
|
5
1
|
export { encodingLength } from "./encodingLength.js";
|
|
2
|
+
export { Encoder, encode } from "./Encoder.js";
|
|
3
|
+
export { Decoder, decode } from "./Decoder.js";
|
|
4
|
+
export { encodeIterable } from "./encodeIterable.js";
|
|
5
|
+
export { decodeIterable } from "./decodeIterable.js";
|
|
6
|
+
export { encodeAsyncIterable } from "./encodeAsyncIterable.js";
|
|
7
|
+
export { decodeAsyncIterable } from "./decodeAsyncIterable.js";
|
|
8
|
+
export { CBORDecoderStream } from "./CBORDecoderStream.js";
|
|
9
|
+
export { CBOREncoderStream } from "./CBOREncoderStream.js";
|
|
6
10
|
export { UnsafeIntegerError } from "./utils.js";
|
package/lib/utils.d.ts
CHANGED
|
@@ -4,3 +4,10 @@ export declare class UnsafeIntegerError extends RangeError {
|
|
|
4
4
|
readonly value: bigint;
|
|
5
5
|
constructor(message: string, value: bigint);
|
|
6
6
|
}
|
|
7
|
+
export declare class AssertError extends Error {
|
|
8
|
+
readonly message: string;
|
|
9
|
+
readonly props?: any | undefined;
|
|
10
|
+
constructor(message: string, props?: any | undefined);
|
|
11
|
+
}
|
|
12
|
+
export declare function assert(condition: unknown, message?: string, props?: any): asserts condition;
|
|
13
|
+
export declare function getByteLength(string: string): number;
|
package/lib/utils.js
CHANGED
|
@@ -6,3 +6,75 @@ export class UnsafeIntegerError extends RangeError {
|
|
|
6
6
|
this.value = value;
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
+
export class AssertError extends Error {
|
|
10
|
+
constructor(message, props) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.message = message;
|
|
13
|
+
this.props = props;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function assert(condition, message = "assertion failed", props) {
|
|
17
|
+
if (!condition) {
|
|
18
|
+
throw new AssertError(message, props);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// https://github.com/feross/buffer/blob/57caad4450d241207066ca3832fb8e9095ad402f/index.js#L434
|
|
22
|
+
export function getByteLength(string) {
|
|
23
|
+
let codePoint;
|
|
24
|
+
const length = string.length;
|
|
25
|
+
let leadSurrogate = null;
|
|
26
|
+
let bytes = 0;
|
|
27
|
+
for (let i = 0; i < length; ++i) {
|
|
28
|
+
codePoint = string.charCodeAt(i);
|
|
29
|
+
// is surrogate component
|
|
30
|
+
if (codePoint > 0xd7ff && codePoint < 0xe000) {
|
|
31
|
+
// last char was a lead
|
|
32
|
+
if (!leadSurrogate) {
|
|
33
|
+
// no lead yet
|
|
34
|
+
if (codePoint > 0xdbff) {
|
|
35
|
+
// unexpected trail
|
|
36
|
+
bytes += 3;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
else if (i + 1 === length) {
|
|
40
|
+
// unpaired lead
|
|
41
|
+
bytes += 3;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
// valid lead
|
|
45
|
+
leadSurrogate = codePoint;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
// 2 leads in a row
|
|
49
|
+
if (codePoint < 0xdc00) {
|
|
50
|
+
bytes += 3;
|
|
51
|
+
leadSurrogate = codePoint;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
// valid surrogate pair
|
|
55
|
+
codePoint = (((leadSurrogate - 0xd800) << 10) | (codePoint - 0xdc00)) + 0x10000;
|
|
56
|
+
}
|
|
57
|
+
else if (leadSurrogate) {
|
|
58
|
+
// valid bmp char, but last char was a lead
|
|
59
|
+
bytes += 3;
|
|
60
|
+
}
|
|
61
|
+
leadSurrogate = null;
|
|
62
|
+
// encode utf8
|
|
63
|
+
if (codePoint < 0x80) {
|
|
64
|
+
bytes += 1;
|
|
65
|
+
}
|
|
66
|
+
else if (codePoint < 0x800) {
|
|
67
|
+
bytes += 2;
|
|
68
|
+
}
|
|
69
|
+
else if (codePoint < 0x10000) {
|
|
70
|
+
bytes += 3;
|
|
71
|
+
}
|
|
72
|
+
else if (codePoint < 0x110000) {
|
|
73
|
+
bytes += 4;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
throw new Error("Invalid code point");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return bytes;
|
|
80
|
+
}
|
package/package.json
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "microcbor",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Encode JavaScript values as canonical CBOR",
|
|
3
|
+
"version": "1.0.0",
|
|
5
4
|
"type": "module",
|
|
6
|
-
"main": "lib/index.js",
|
|
7
|
-
"types": "lib/index.d.ts",
|
|
8
5
|
"files": [
|
|
9
6
|
"lib"
|
|
10
7
|
],
|
|
8
|
+
"description": "Encode JavaScript values as canonical CBOR",
|
|
9
|
+
"main": "lib/index.js",
|
|
10
|
+
"types": "./lib/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": "./lib/index.js"
|
|
13
|
+
},
|
|
11
14
|
"scripts": {
|
|
12
|
-
"
|
|
15
|
+
"dev": "tsc --build tsconfig.json test/tsconfig.json --watch",
|
|
16
|
+
"build": "tsc --build tsconfig.json test/tsconfig.json",
|
|
17
|
+
"clean": "tsc --build tsconfig.json test/tsconfig.json --clean",
|
|
13
18
|
"test": "ava"
|
|
14
19
|
},
|
|
15
20
|
"repository": {
|
|
@@ -27,11 +32,13 @@
|
|
|
27
32
|
},
|
|
28
33
|
"homepage": "https://github.com/joeltg/microcbor#readme",
|
|
29
34
|
"devDependencies": {
|
|
30
|
-
"ava": "^5.
|
|
31
|
-
"
|
|
32
|
-
"
|
|
35
|
+
"@ava/typescript": "^5.0.0",
|
|
36
|
+
"@types/node": "^22.13.9",
|
|
37
|
+
"ava": "^6.2.0",
|
|
38
|
+
"cbor": "^10.0.3",
|
|
39
|
+
"typescript": "^5.6.0"
|
|
33
40
|
},
|
|
34
41
|
"dependencies": {
|
|
35
|
-
"fp16": "^0.
|
|
42
|
+
"fp16": "^1.0.0"
|
|
36
43
|
}
|
|
37
44
|
}
|
package/lib/decodeStream.d.ts
DELETED
package/lib/encode.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { CBORValue } from "./types.js";
|
|
2
|
-
export declare class Encoder {
|
|
3
|
-
static defaultChunkSize: number;
|
|
4
|
-
closed: boolean;
|
|
5
|
-
private buffer;
|
|
6
|
-
private view;
|
|
7
|
-
private offset;
|
|
8
|
-
private readonly encoder;
|
|
9
|
-
private readonly chunkSize;
|
|
10
|
-
constructor(options?: {
|
|
11
|
-
chunkSize?: number;
|
|
12
|
-
noCopy?: boolean;
|
|
13
|
-
});
|
|
14
|
-
private allocate;
|
|
15
|
-
private float16;
|
|
16
|
-
private float32;
|
|
17
|
-
private float64;
|
|
18
|
-
private uint8;
|
|
19
|
-
private uint16;
|
|
20
|
-
private uint32;
|
|
21
|
-
private uint64;
|
|
22
|
-
private encodeTypeAndArgument;
|
|
23
|
-
private encodeNumber;
|
|
24
|
-
private encodeInteger;
|
|
25
|
-
private encodeFloat;
|
|
26
|
-
private encodeString;
|
|
27
|
-
private encodeBytes;
|
|
28
|
-
encodeValue(value: CBORValue): Iterable<Uint8Array>;
|
|
29
|
-
flush(): Iterable<Uint8Array>;
|
|
30
|
-
private static compareKeys;
|
|
31
|
-
private static getAdditionalInformation;
|
|
32
|
-
}
|
|
33
|
-
export declare function encode(value: CBORValue, options?: {
|
|
34
|
-
chunkSize?: number;
|
|
35
|
-
}): Uint8Array;
|
package/lib/encode.js
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
import { getFloat16Precision, getFloat32Precision, setFloat16, Precision, } from "fp16";
|
|
2
|
-
export class Encoder {
|
|
3
|
-
constructor(options = {}) {
|
|
4
|
-
this.encoder = new TextEncoder();
|
|
5
|
-
this.chunkSize = options.chunkSize || Encoder.defaultChunkSize;
|
|
6
|
-
this.buffer = new ArrayBuffer(this.chunkSize);
|
|
7
|
-
this.view = new DataView(this.buffer);
|
|
8
|
-
this.offset = 0;
|
|
9
|
-
this.closed = false;
|
|
10
|
-
}
|
|
11
|
-
*allocate(size) {
|
|
12
|
-
if (this.buffer.byteLength < this.offset + size) {
|
|
13
|
-
yield new Uint8Array(this.buffer, 0, this.offset);
|
|
14
|
-
const byteLength = Math.max(size, this.chunkSize);
|
|
15
|
-
this.buffer = new ArrayBuffer(byteLength);
|
|
16
|
-
this.view = new DataView(this.buffer);
|
|
17
|
-
this.offset = 0;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
*float16(value) {
|
|
21
|
-
yield* this.allocate(2);
|
|
22
|
-
setFloat16(this.view, this.offset, value);
|
|
23
|
-
this.offset += 2;
|
|
24
|
-
}
|
|
25
|
-
*float32(value) {
|
|
26
|
-
yield* this.allocate(4);
|
|
27
|
-
this.view.setFloat32(this.offset, value);
|
|
28
|
-
this.offset += 4;
|
|
29
|
-
}
|
|
30
|
-
*float64(value) {
|
|
31
|
-
yield* this.allocate(8);
|
|
32
|
-
this.view.setFloat64(this.offset, value);
|
|
33
|
-
this.offset += 8;
|
|
34
|
-
}
|
|
35
|
-
*uint8(value) {
|
|
36
|
-
yield* this.allocate(1);
|
|
37
|
-
this.view.setUint8(this.offset, value);
|
|
38
|
-
this.offset += 1;
|
|
39
|
-
}
|
|
40
|
-
*uint16(value) {
|
|
41
|
-
yield* this.allocate(2);
|
|
42
|
-
this.view.setUint16(this.offset, value);
|
|
43
|
-
this.offset += 2;
|
|
44
|
-
}
|
|
45
|
-
*uint32(value) {
|
|
46
|
-
yield* this.allocate(4);
|
|
47
|
-
this.view.setUint32(this.offset, value);
|
|
48
|
-
this.offset += 4;
|
|
49
|
-
}
|
|
50
|
-
*uint64(value) {
|
|
51
|
-
yield* this.allocate(8);
|
|
52
|
-
this.view.setBigUint64(this.offset, BigInt(value));
|
|
53
|
-
this.offset += 8;
|
|
54
|
-
}
|
|
55
|
-
*encodeTypeAndArgument(type, argument) {
|
|
56
|
-
const additionalInformation = Encoder.getAdditionalInformation(argument);
|
|
57
|
-
yield* this.uint8((type << 5) | additionalInformation);
|
|
58
|
-
switch (additionalInformation) {
|
|
59
|
-
case 24:
|
|
60
|
-
return yield* this.uint8(argument);
|
|
61
|
-
case 25:
|
|
62
|
-
return yield* this.uint16(argument);
|
|
63
|
-
case 26:
|
|
64
|
-
return yield* this.uint32(argument);
|
|
65
|
-
case 27:
|
|
66
|
-
return yield* this.uint64(argument);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
*encodeNumber(value) {
|
|
70
|
-
if (Object.is(value, 0)) {
|
|
71
|
-
yield* this.encodeInteger(value);
|
|
72
|
-
}
|
|
73
|
-
else if (Object.is(value, -0)) {
|
|
74
|
-
yield* this.encodeFloat(value);
|
|
75
|
-
}
|
|
76
|
-
else if (Math.floor(value) === value &&
|
|
77
|
-
Number.MIN_SAFE_INTEGER <= value &&
|
|
78
|
-
value <= Number.MAX_SAFE_INTEGER) {
|
|
79
|
-
yield* this.encodeInteger(value);
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
yield* this.encodeFloat(value);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
*encodeInteger(value) {
|
|
86
|
-
if (value < 0) {
|
|
87
|
-
yield* this.encodeTypeAndArgument(1, -value - 1);
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
yield* this.encodeTypeAndArgument(0, value);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
*encodeFloat(value) {
|
|
94
|
-
if (getFloat16Precision(value) === Precision.Exact) {
|
|
95
|
-
yield* this.uint8(0xe0 | 25);
|
|
96
|
-
yield* this.float16(value);
|
|
97
|
-
}
|
|
98
|
-
else if (getFloat32Precision(value) === Precision.Exact) {
|
|
99
|
-
yield* this.uint8(0xe0 | 26);
|
|
100
|
-
yield* this.float32(value);
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
yield* this.uint8(0xe0 | 27);
|
|
104
|
-
yield* this.float64(value);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
*encodeString(value) {
|
|
108
|
-
const data = this.encoder.encode(value);
|
|
109
|
-
yield* this.encodeTypeAndArgument(3, data.byteLength);
|
|
110
|
-
yield* this.allocate(data.byteLength);
|
|
111
|
-
new Uint8Array(this.buffer, this.offset).set(data);
|
|
112
|
-
this.offset += data.byteLength;
|
|
113
|
-
}
|
|
114
|
-
*encodeBytes(value) {
|
|
115
|
-
yield* this.encodeTypeAndArgument(2, value.byteLength);
|
|
116
|
-
yield* this.allocate(value.byteLength);
|
|
117
|
-
new Uint8Array(this.buffer, this.offset, value.byteLength).set(value);
|
|
118
|
-
this.offset += value.byteLength;
|
|
119
|
-
}
|
|
120
|
-
*encodeValue(value) {
|
|
121
|
-
if (this.closed) {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
if (value === false) {
|
|
125
|
-
yield* this.uint8(0xf4);
|
|
126
|
-
}
|
|
127
|
-
else if (value === true) {
|
|
128
|
-
yield* this.uint8(0xf5);
|
|
129
|
-
}
|
|
130
|
-
else if (value === null) {
|
|
131
|
-
yield* this.uint8(0xf6);
|
|
132
|
-
}
|
|
133
|
-
else if (value === undefined) {
|
|
134
|
-
yield* this.uint8(0xf7);
|
|
135
|
-
}
|
|
136
|
-
else if (typeof value === "number") {
|
|
137
|
-
yield* this.encodeNumber(value);
|
|
138
|
-
}
|
|
139
|
-
else if (typeof value === "string") {
|
|
140
|
-
yield* this.encodeString(value);
|
|
141
|
-
}
|
|
142
|
-
else if (value instanceof Uint8Array) {
|
|
143
|
-
yield* this.encodeBytes(value);
|
|
144
|
-
}
|
|
145
|
-
else if (Array.isArray(value)) {
|
|
146
|
-
yield* this.encodeTypeAndArgument(4, value.length);
|
|
147
|
-
for (const element of value) {
|
|
148
|
-
yield* this.encodeValue(element);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
const keys = Object.keys(value).sort(Encoder.compareKeys);
|
|
153
|
-
yield* this.encodeTypeAndArgument(5, keys.length);
|
|
154
|
-
for (const key of keys) {
|
|
155
|
-
yield* this.encodeString(key);
|
|
156
|
-
yield* this.encodeValue(value[key]);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
*flush() {
|
|
161
|
-
if (this.closed) {
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
this.closed = true;
|
|
165
|
-
if (this.offset > 0) {
|
|
166
|
-
yield new Uint8Array(this.buffer, 0, this.offset);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
// Per the deterministic CBOR spec, we're supposed to sort keys
|
|
170
|
-
// the byte-wise lexicographic order of the key's CBOR encoding
|
|
171
|
-
// - ie lower major types come before higher major types!
|
|
172
|
-
// However, microcbor only supports string keys, which means we
|
|
173
|
-
// can get away with sorting them without actually encoding them
|
|
174
|
-
// first. One thing we know for sure about strings is that a
|
|
175
|
-
// string with a smaller length will sort byte-wise before a string
|
|
176
|
-
// with a longer length, since strings are encoded with a length
|
|
177
|
-
// prefix (either in the additionalInformation bits, if < 24, or
|
|
178
|
-
// in the next serveral bytes, but in all cases the order holds).
|
|
179
|
-
static compareKeys(a, b) {
|
|
180
|
-
if (a.length < b.length) {
|
|
181
|
-
return -1;
|
|
182
|
-
}
|
|
183
|
-
else if (b.length < a.length) {
|
|
184
|
-
return 1;
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
return a < b ? -1 : 1;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
static getAdditionalInformation(argument) {
|
|
191
|
-
if (argument < 24) {
|
|
192
|
-
return argument;
|
|
193
|
-
}
|
|
194
|
-
else if (argument < 0x100) {
|
|
195
|
-
return 24;
|
|
196
|
-
}
|
|
197
|
-
else if (argument < 0x10000) {
|
|
198
|
-
return 25;
|
|
199
|
-
}
|
|
200
|
-
else if (argument < 0x100000000) {
|
|
201
|
-
return 26;
|
|
202
|
-
}
|
|
203
|
-
else {
|
|
204
|
-
return 27;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
Encoder.defaultChunkSize = 512;
|
|
209
|
-
export function encode(value, options = {}) {
|
|
210
|
-
const encoder = new Encoder(options);
|
|
211
|
-
let byteLength = 0;
|
|
212
|
-
const chunks = [];
|
|
213
|
-
for (const chunk of encoder.encodeValue(value)) {
|
|
214
|
-
chunks.push(chunk);
|
|
215
|
-
byteLength += chunk.byteLength;
|
|
216
|
-
}
|
|
217
|
-
for (const chunk of encoder.flush()) {
|
|
218
|
-
chunks.push(chunk);
|
|
219
|
-
byteLength += chunk.byteLength;
|
|
220
|
-
}
|
|
221
|
-
const data = new Uint8Array(byteLength);
|
|
222
|
-
let offset = 0;
|
|
223
|
-
for (const chunk of chunks) {
|
|
224
|
-
data.set(chunk, offset);
|
|
225
|
-
offset += chunk.length;
|
|
226
|
-
}
|
|
227
|
-
return data;
|
|
228
|
-
}
|
package/lib/encodeStream.d.ts
DELETED
package/lib/encodeStream.js
DELETED