@atcute/cbor 2.0.1 → 2.1.1

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/dist/decode.js CHANGED
@@ -1,19 +1,23 @@
1
1
  import { CidLinkWrapper } from '@atcute/cid';
2
+ import { decodeUtf8From } from '@atcute/uint8array';
2
3
  import { toBytes } from './bytes.js';
3
- const utf8d = new TextDecoder();
4
4
  const readArgument = (state, info) => {
5
5
  if (info < 24) {
6
6
  return info;
7
7
  }
8
8
  switch (info) {
9
- case 24:
9
+ case 24: {
10
10
  return readUint8(state);
11
- case 25:
11
+ }
12
+ case 25: {
12
13
  return readUint16(state);
13
- case 26:
14
+ }
15
+ case 26: {
14
16
  return readUint32(state);
15
- case 27:
16
- return readUint64(state);
17
+ }
18
+ case 27: {
19
+ return readUint53(state);
20
+ }
17
21
  }
18
22
  throw new Error(`invalid argument encoding; got ${info}`);
19
23
  };
@@ -23,39 +27,47 @@ const readFloat64 = (state) => {
23
27
  return value;
24
28
  };
25
29
  const readUint8 = (state) => {
26
- const value = state.v.getUint8(state.p);
27
- state.p += 1;
28
- return value;
30
+ return state.b[state.p++];
29
31
  };
30
32
  const readUint16 = (state) => {
31
- const value = state.v.getUint16(state.p);
32
- state.p += 2;
33
+ let pos = state.p;
34
+ const buf = state.b;
35
+ const value = (buf[pos++] << 8) | buf[pos++];
36
+ state.p = pos;
33
37
  return value;
34
38
  };
35
39
  const readUint32 = (state) => {
36
- const value = state.v.getUint32(state.p);
37
- state.p += 4;
40
+ let pos = state.p;
41
+ const buf = state.b;
42
+ const value = ((buf[pos++] << 24) | (buf[pos++] << 16) | (buf[pos++] << 8) | buf[pos++]) >>> 0;
43
+ state.p = pos;
38
44
  return value;
39
45
  };
40
- const readUint64 = (state) => {
41
- const hi = state.v.getUint32(state.p);
42
- const lo = state.v.getUint32(state.p + 4);
46
+ const readUint53 = (state) => {
47
+ let pos = state.p;
48
+ const buf = state.b;
49
+ const hi = ((buf[pos++] << 24) | (buf[pos++] << 16) | (buf[pos++] << 8) | buf[pos++]) >>> 0;
43
50
  if (hi > 0x1fffff) {
44
51
  throw new RangeError(`can't decode integers beyond safe integer range`);
45
52
  }
46
- // prettier-ignore
47
- const value = (hi * (2 ** 32)) + lo;
48
- state.p += 8;
53
+ const lo = ((buf[pos++] << 24) | (buf[pos++] << 16) | (buf[pos++] << 8) | buf[pos++]) >>> 0;
54
+ const value = hi * 2 ** 32 + lo;
55
+ state.p = pos;
49
56
  return value;
50
57
  };
51
58
  const readString = (state, length) => {
52
- const slice = state.b.subarray(state.p, (state.p += length));
53
- return utf8d.decode(slice);
59
+ const string = decodeUtf8From(state.b, state.p, length);
60
+ state.p += length;
61
+ return string;
54
62
  };
55
63
  const readBytes = (state, length) => {
56
64
  const slice = state.b.subarray(state.p, (state.p += length));
57
65
  return toBytes(slice);
58
66
  };
67
+ const readTypeInfo = (state) => {
68
+ const prelude = readUint8(state);
69
+ return [prelude >> 5, prelude & 0x1f];
70
+ };
59
71
  const readCid = (state, length) => {
60
72
  // CID bytes are prefixed with 0x00 for historical reasons, apparently.
61
73
  const slice = state.b.subarray(state.p + 1, (state.p += length));
@@ -65,68 +77,69 @@ const readValue = (state) => {
65
77
  const prelude = readUint8(state);
66
78
  const type = prelude >> 5;
67
79
  const info = prelude & 0x1f;
68
- if (type === 0) {
69
- const value = readArgument(state, info);
70
- return value;
71
- }
72
- if (type === 1) {
73
- const value = readArgument(state, info);
74
- return -1 - value;
75
- }
76
- if (type === 2) {
77
- const len = readArgument(state, info);
78
- return readBytes(state, len);
79
- }
80
- if (type === 3) {
81
- const len = readArgument(state, info);
82
- return readString(state, len);
83
- }
84
- if (type === 4) {
85
- const len = readArgument(state, info);
86
- const array = new Array(len);
87
- for (let idx = 0; idx < len; idx++) {
88
- array[idx] = readValue(state);
80
+ const arg = type < 7 ? readArgument(state, info) : 0;
81
+ switch (type) {
82
+ case 0: {
83
+ return arg;
89
84
  }
90
- return array;
91
- }
92
- if (type === 5) {
93
- const len = readArgument(state, info);
94
- const object = {};
95
- for (let idx = 0; idx < len; idx++) {
96
- const key = readValue(state);
97
- if (typeof key !== 'string') {
98
- throw new TypeError(`expected map to only have string keys; got ${typeof key}`);
85
+ case 1: {
86
+ return -1 - arg;
87
+ }
88
+ case 2: {
89
+ return readBytes(state, arg);
90
+ }
91
+ case 3: {
92
+ return readString(state, arg);
93
+ }
94
+ case 4: {
95
+ const array = new Array(arg);
96
+ for (let idx = 0; idx < arg; idx++) {
97
+ array[idx] = readValue(state);
99
98
  }
100
- object[key] = readValue(state);
99
+ return array;
101
100
  }
102
- return object;
103
- }
104
- if (type === 6) {
105
- const tag = readArgument(state, info);
106
- if (tag === 42) {
107
- const prelude = readUint8(state);
108
- const type = prelude >> 5;
109
- const info = prelude & 0x1f;
110
- if (type !== 2) {
111
- throw new TypeError(`expected cid tag to have bytes value; got ${type}`);
101
+ case 5: {
102
+ const object = {};
103
+ for (let idx = 0; idx < arg; idx++) {
104
+ const [type, info] = readTypeInfo(state);
105
+ if (type !== 3) {
106
+ throw new TypeError(`expected map to only have string keys; got type ${type}`);
107
+ }
108
+ const len = readArgument(state, info);
109
+ const key = readString(state, len);
110
+ if (key === '__proto__')
111
+ // Guard against prototype pollution. CWE-1321
112
+ Object.defineProperty(object, key, { enumerable: true, configurable: true, writable: true });
113
+ object[key] = readValue(state);
112
114
  }
113
- const len = readArgument(state, info);
114
- return readCid(state, len);
115
+ return object;
115
116
  }
116
- throw new TypeError(`unsupported tag; got ${tag}`);
117
- }
118
- if (type === 7) {
119
- switch (info) {
120
- case 20:
121
- return false;
122
- case 21:
123
- return true;
124
- case 22:
125
- return null;
126
- case 27:
127
- return readFloat64(state);
117
+ case 6: {
118
+ if (arg === 42) {
119
+ const [type, info] = readTypeInfo(state);
120
+ if (type !== 2) {
121
+ throw new TypeError(`expected cid-link to be type 2 (bytes); got type ${type}`);
122
+ }
123
+ const len = readArgument(state, info);
124
+ return readCid(state, len);
125
+ }
126
+ throw new TypeError(`unsupported tag; got ${arg}`);
127
+ }
128
+ case 7: {
129
+ switch (info) {
130
+ case 20:
131
+ case 21: {
132
+ return info === 21;
133
+ }
134
+ case 22: {
135
+ return null;
136
+ }
137
+ case 27: {
138
+ return readFloat64(state);
139
+ }
140
+ }
141
+ throw new Error(`invalid simple value; got ${info}`);
128
142
  }
129
- throw new Error(`invalid simple value; got ${info}`);
130
143
  }
131
144
  throw new TypeError(`invalid type; got ${type}`);
132
145
  };
@@ -1 +1 @@
1
- {"version":3,"file":"decode.js","sourceRoot":"","sources":["../lib/decode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAgB,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,OAAO,EAAc,MAAM,YAAY,CAAC;AAEjD,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC;AAQhC,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,IAAY,EAAU,EAAE;IAC3D,IAAI,IAAI,GAAG,EAAE,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACb,CAAC;IAED,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,EAAE;YACN,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;QACzB,KAAK,EAAE;YACN,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;QAC1B,KAAK,EAAE;YACN,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;QAC1B,KAAK,EAAE;YACN,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,EAAE,CAAC,CAAC;AAC3D,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,KAAY,EAAU,EAAE;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAE1C,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,KAAK,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,KAAY,EAAU,EAAE;IAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAExC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,KAAK,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,KAAY,EAAU,EAAE;IAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEzC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,KAAK,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,KAAY,EAAU,EAAE;IAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEzC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,KAAK,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,KAAY,EAAU,EAAE;IAC3C,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACtC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAE1C,IAAI,EAAE,GAAG,QAAQ,EAAE,CAAC;QACnB,MAAM,IAAI,UAAU,CAAC,iDAAiD,CAAC,CAAC;IACzE,CAAC;IAED,kBAAkB;IAClB,MAAM,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IAEpC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,KAAK,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,KAAY,EAAE,MAAc,EAAU,EAAE;IAC3D,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC;IAE7D,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,KAAY,EAAE,MAAc,EAAS,EAAE;IACzD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC;IAE7D,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC,CAAC;AAEF,MAAM,OAAO,GAAG,CAAC,KAAY,EAAE,MAAc,EAAW,EAAE;IACzD,uEAAuE;IACvE,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC;IAEjE,OAAO,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,KAAY,EAAO,EAAE;IACvC,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAEjC,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,CAAC;IAC1B,MAAM,IAAI,GAAG,OAAO,GAAG,IAAI,CAAC;IAE5B,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QAChB,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC;IACd,CAAC;IAED,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QAChB,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACxC,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC;IACnB,CAAC;IAED,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QAChB,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACtC,OAAO,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QAChB,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAEtC,OAAO,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QAChB,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;QAE7B,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC;YACpC,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QAED,OAAO,KAAK,CAAC;IACd,CAAC;IAED,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QAChB,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACtC,MAAM,MAAM,GAA4B,EAAE,CAAC;QAE3C,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC;YACpC,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAC7B,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC7B,MAAM,IAAI,SAAS,CAAC,8CAA8C,OAAO,GAAG,EAAE,CAAC,CAAC;YACjF,CAAC;YAED,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,OAAO,MAAM,CAAC;IACf,CAAC;IAED,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QAChB,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAEtC,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;YAChB,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAEjC,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,CAAC;YAC1B,MAAM,IAAI,GAAG,OAAO,GAAG,IAAI,CAAC;YAE5B,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBAChB,MAAM,IAAI,SAAS,CAAC,6CAA6C,IAAI,EAAE,CAAC,CAAC;YAC1E,CAAC;YAED,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAEtC,OAAO,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC5B,CAAC;QAED,MAAM,IAAI,SAAS,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QAChB,QAAQ,IAAI,EAAE,CAAC;YACd,KAAK,EAAE;gBACN,OAAO,KAAK,CAAC;YACd,KAAK,EAAE;gBACN,OAAO,IAAI,CAAC;YACb,KAAK,EAAE;gBACN,OAAO,IAAI,CAAC;YACb,KAAK,EAAE;gBACN,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,IAAI,SAAS,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC;AAClD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAe,EAAuC,EAAE;IACnF,MAAM,KAAK,GAAU;QACpB,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC;QAC3D,CAAC,EAAE,CAAC;KACJ,CAAC;IAEF,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAExC,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AAC3B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,GAAe,EAAO,EAAE;IAC9C,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,KAAK,CAAC;AACd,CAAC,CAAC"}
1
+ {"version":3,"file":"decode.js","sourceRoot":"","sources":["../lib/decode.ts"],"names":[],"mappings":"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"}
package/dist/encode.js CHANGED
@@ -1,77 +1,88 @@
1
1
  import { CidLinkWrapper, fromString } from '@atcute/cid';
2
+ import { allocUnsafe, concat, encodeUtf8Into } from '@atcute/uint8array';
2
3
  import { BytesWrapper, fromBytes } from './bytes.js';
4
+ const MAX_TYPE_ARG_LEN = 9;
3
5
  const CHUNK_SIZE = 1024;
4
- const utf8e = new TextEncoder();
6
+ const _max = Math.max;
7
+ const _isInteger = Number.isInteger;
8
+ const _isNaN = Number.isNaN;
9
+ const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER;
10
+ const MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER;
5
11
  const resizeIfNeeded = (state, needed) => {
6
12
  const buf = state.b;
7
13
  const pos = state.p;
8
14
  if (buf.byteLength < pos + needed) {
9
- state.c.push(new Uint8Array(buf, 0, pos));
10
- state.b = new ArrayBuffer(Math.max(CHUNK_SIZE, needed));
11
- state.v = new DataView(state.b);
15
+ state.c.push(buf.subarray(0, pos));
16
+ state.l += pos;
17
+ state.v = new DataView((state.b = allocUnsafe(_max(CHUNK_SIZE, needed))).buffer);
12
18
  state.p = 0;
13
19
  }
14
20
  };
15
- const getInfo = (arg) => {
16
- if (arg < 24) {
17
- return arg;
18
- }
19
- else if (arg < 0x100) {
20
- return 24;
21
- }
22
- else if (arg < 0x10000) {
23
- return 25;
24
- }
25
- else if (arg < 0x100000000) {
26
- return 26;
27
- }
28
- else {
29
- return 27;
30
- }
21
+ const getTypeInfoLength = (arg) => {
22
+ return arg < 24 ? 1 : arg < 0x100 ? 2 : arg < 0x10000 ? 3 : arg < 0x100000000 ? 5 : 9;
31
23
  };
32
24
  const writeFloat64 = (state, val) => {
33
- resizeIfNeeded(state, 8);
34
25
  state.v.setFloat64(state.p, val);
35
26
  state.p += 8;
36
27
  };
37
28
  const writeUint8 = (state, val) => {
38
- resizeIfNeeded(state, 1);
39
- state.v.setUint8(state.p, val);
40
- state.p += 1;
29
+ state.b[state.p++] = val;
41
30
  };
42
31
  const writeUint16 = (state, val) => {
43
- resizeIfNeeded(state, 2);
44
- state.v.setUint16(state.p, val);
45
- state.p += 2;
32
+ let pos = state.p;
33
+ const buf = state.b;
34
+ buf[pos++] = val >>> 8;
35
+ buf[pos++] = val & 0xff;
36
+ state.p = pos;
46
37
  };
47
38
  const writeUint32 = (state, val) => {
48
- resizeIfNeeded(state, 4);
49
- state.v.setUint32(state.p, val);
50
- state.p += 4;
39
+ let pos = state.p;
40
+ const buf = state.b;
41
+ buf[pos++] = val >>> 24;
42
+ buf[pos++] = (val >>> 16) & 0xff;
43
+ buf[pos++] = (val >>> 8) & 0xff;
44
+ buf[pos++] = val & 0xff;
45
+ state.p = pos;
51
46
  };
52
- const writeUint64 = (state, val) => {
47
+ const writeUint53 = (state, val) => {
48
+ let pos = state.p;
49
+ const buf = state.b;
53
50
  const hi = (val / 2 ** 32) | 0;
54
51
  const lo = val >>> 0;
55
- resizeIfNeeded(state, 8);
56
- state.v.setUint32(state.p, hi);
57
- state.v.setUint32(state.p + 4, lo);
58
- state.p += 8;
52
+ buf[pos++] = hi >>> 24;
53
+ buf[pos++] = (hi >>> 16) & 0xff;
54
+ buf[pos++] = (hi >>> 8) & 0xff;
55
+ buf[pos++] = hi & 0xff;
56
+ buf[pos++] = lo >>> 24;
57
+ buf[pos++] = (lo >>> 16) & 0xff;
58
+ buf[pos++] = (lo >>> 8) & 0xff;
59
+ buf[pos++] = lo & 0xff;
60
+ state.p = pos;
59
61
  };
60
62
  const writeTypeAndArgument = (state, type, arg) => {
61
- const info = getInfo(arg);
62
- writeUint8(state, (type << 5) | info);
63
- switch (info) {
64
- case 24:
65
- return writeUint8(state, arg);
66
- case 25:
67
- return writeUint16(state, arg);
68
- case 26:
69
- return writeUint32(state, arg);
70
- case 27:
71
- return writeUint64(state, arg);
63
+ if (arg < 24) {
64
+ writeUint8(state, (type << 5) | arg);
65
+ }
66
+ else if (arg < 0x100) {
67
+ writeUint8(state, (type << 5) | 24);
68
+ writeUint8(state, arg);
69
+ }
70
+ else if (arg < 0x10000) {
71
+ writeUint8(state, (type << 5) | 25);
72
+ writeUint16(state, arg);
73
+ }
74
+ else if (arg < 0x100000000) {
75
+ writeUint8(state, (type << 5) | 26);
76
+ writeUint32(state, arg);
77
+ }
78
+ else {
79
+ writeUint8(state, (type << 5) | 27);
80
+ writeUint53(state, arg);
72
81
  }
73
82
  };
83
+ // --- Functions below MUST be cautious about ensuring there's enough room in the buffer!!
74
84
  const writeInteger = (state, val) => {
85
+ resizeIfNeeded(state, MAX_TYPE_ARG_LEN);
75
86
  if (val < 0) {
76
87
  writeTypeAndArgument(state, 1, -val - 1);
77
88
  }
@@ -80,154 +91,172 @@ const writeInteger = (state, val) => {
80
91
  }
81
92
  };
82
93
  const writeFloat = (state, val) => {
94
+ resizeIfNeeded(state, 9);
83
95
  writeUint8(state, 0xe0 | 27);
84
96
  writeFloat64(state, val);
85
97
  };
86
98
  const writeNumber = (state, val) => {
87
- if (Number.isNaN(val)) {
99
+ if (_isNaN(val)) {
88
100
  throw new RangeError(`NaN values not supported`);
89
101
  }
90
- if (val > Number.MAX_SAFE_INTEGER || val < Number.MIN_SAFE_INTEGER) {
102
+ if (val > MAX_SAFE_INTEGER || val < MIN_SAFE_INTEGER) {
91
103
  throw new RangeError(`can't encode numbers beyond safe integer range`);
92
104
  }
93
- if (Number.isInteger(val)) {
105
+ if (_isInteger(val)) {
94
106
  writeInteger(state, val);
95
107
  }
96
108
  else {
109
+ // Note: https://atproto.com/specs/data-model#:~:text=not%20allowed%20in%20atproto
97
110
  writeFloat(state, val);
98
111
  }
99
112
  };
100
113
  const writeString = (state, val) => {
101
- const buf = utf8e.encode(val);
102
- const len = buf.byteLength;
114
+ // JS strings are UTF-16 (ECMA spec)
115
+ // Therefore, worst case length of UTF-8 is length * 3. (plus 9 bytes of CBOR header)
116
+ // Greatly overshoots in practice, but doesn't matter. (alloc is O(1)+ anyway)
117
+ const strLength = val.length;
118
+ resizeIfNeeded(state, strLength * 3 + MAX_TYPE_ARG_LEN);
119
+ // Credit: method used by cbor-x
120
+ // Rather than allocate a buffer and then copy it back to the destination buffer:
121
+ // - Estimate the length of the header based on the UTF-16 size of the string.
122
+ // Should be accurate most of the time, see last point for when it isn't.
123
+ // - Directly write the string at the estimated location, retrieving with it the actual length.
124
+ // - Write the header now that the length is available.
125
+ // - If the estimation happened to be wrong, correct the placement of the string.
126
+ // While it's costly, it's actually roughly the same cost as if we encoded it separately + copy.
127
+ const estimatedHeaderSize = getTypeInfoLength(strLength);
128
+ const estimatedPosition = state.p + estimatedHeaderSize;
129
+ const len = encodeUtf8Into(state.b, val, estimatedPosition);
130
+ const headerSize = getTypeInfoLength(len);
131
+ if (estimatedHeaderSize !== headerSize) {
132
+ // Estimation was incorrect, move the bytes to the real place.
133
+ state.b.copyWithin(state.p + headerSize, estimatedPosition, estimatedPosition + len);
134
+ }
103
135
  writeTypeAndArgument(state, 3, len);
104
- resizeIfNeeded(state, len);
105
- new Uint8Array(state.b, state.p).set(buf);
106
136
  state.p += len;
107
137
  };
108
138
  const writeBytes = (state, val) => {
109
139
  const buf = fromBytes(val);
110
140
  const len = buf.byteLength;
141
+ resizeIfNeeded(state, len + MAX_TYPE_ARG_LEN);
111
142
  writeTypeAndArgument(state, 2, len);
112
- resizeIfNeeded(state, len);
113
- new Uint8Array(state.b, state.p, len).set(buf);
143
+ state.b.set(buf, state.p);
114
144
  state.p += len;
115
145
  };
116
146
  const writeCid = (state, val) => {
117
147
  // CID bytes are prefixed with 0x00 for historical reasons, apparently.
118
148
  const buf = val instanceof CidLinkWrapper ? val.bytes : fromString(val.$link).bytes;
119
149
  const len = buf.byteLength + 1;
150
+ resizeIfNeeded(state, len + 2 * MAX_TYPE_ARG_LEN);
120
151
  writeTypeAndArgument(state, 6, 42);
121
152
  writeTypeAndArgument(state, 2, len);
122
- resizeIfNeeded(state, len);
123
- new Uint8Array(state.b, state.p + 1, len - 1).set(buf);
153
+ state.b[state.p] = 0;
154
+ state.b.set(buf, state.p + 1);
124
155
  state.p += len;
125
156
  };
126
157
  const writeValue = (state, val) => {
127
- if (val === undefined) {
128
- throw new TypeError(`undefined values not supported`);
129
- }
130
- if (val === null) {
131
- return writeUint8(state, 0xf6);
132
- }
133
- if (val === false) {
134
- return writeUint8(state, 0xf4);
135
- }
136
- if (val === true) {
137
- return writeUint8(state, 0xf5);
138
- }
139
- if (typeof val === 'number') {
140
- return writeNumber(state, val);
141
- }
142
- if (typeof val === 'string') {
143
- return writeString(state, val);
144
- }
145
- if (typeof val === 'object') {
146
- if (isArray(val)) {
147
- const len = val.length;
148
- writeTypeAndArgument(state, 4, len);
149
- for (let idx = 0; idx < len; idx++) {
150
- const v = val[idx];
151
- writeValue(state, v);
152
- }
153
- return;
158
+ switch (typeof val) {
159
+ case 'boolean': {
160
+ resizeIfNeeded(state, 1);
161
+ return writeUint8(state, 0xf4 + +val);
154
162
  }
155
- if ('$link' in val) {
156
- if (val instanceof CidLinkWrapper || typeof val.$link === 'string') {
157
- writeCid(state, val);
158
- return;
159
- }
160
- throw new TypeError(`unexpected cid-link value`);
163
+ case 'number': {
164
+ return writeNumber(state, val);
165
+ }
166
+ case 'string': {
167
+ return writeString(state, val);
161
168
  }
162
- if ('$bytes' in val) {
163
- if (val instanceof BytesWrapper || typeof val.$bytes === 'string') {
164
- writeBytes(state, val);
169
+ case 'object': {
170
+ // case: null
171
+ if (val === null) {
172
+ resizeIfNeeded(state, 1);
173
+ return writeUint8(state, 0xf6);
174
+ }
175
+ // case: array
176
+ if (Array.isArray(val)) {
177
+ const len = val.length;
178
+ resizeIfNeeded(state, MAX_TYPE_ARG_LEN);
179
+ writeTypeAndArgument(state, 4, len);
180
+ for (let idx = 0; idx < len; idx++) {
181
+ writeValue(state, val[idx]);
182
+ }
165
183
  return;
166
184
  }
167
- throw new TypeError(`unexpected bytes value`);
168
- }
169
- if (isPlainObject(val)) {
170
- const keys = Object.keys(val)
171
- .filter((key) => typeof key === 'string' && val[key] !== undefined)
172
- .sort(compareKeys);
173
- const len = keys.length;
174
- writeTypeAndArgument(state, 5, len);
175
- for (let idx = 0; idx < len; idx++) {
176
- const key = keys[idx];
177
- writeString(state, key);
178
- writeValue(state, val[key]);
185
+ // case: cid-link
186
+ if ('$link' in val) {
187
+ if (val instanceof CidLinkWrapper || typeof val.$link === 'string') {
188
+ writeCid(state, val);
189
+ return;
190
+ }
191
+ throw new TypeError(`unexpected cid-link value`);
192
+ }
193
+ // case: bytes
194
+ if ('$bytes' in val) {
195
+ if (val instanceof BytesWrapper || typeof val.$bytes === 'string') {
196
+ writeBytes(state, val);
197
+ return;
198
+ }
199
+ throw new TypeError(`unexpected bytes value`);
200
+ }
201
+ // case: POJO
202
+ if (val.constructor === Object) {
203
+ const keys = getOrderedObjectKeys(val);
204
+ const len = keys.length;
205
+ resizeIfNeeded(state, MAX_TYPE_ARG_LEN);
206
+ writeTypeAndArgument(state, 5, len);
207
+ for (let idx = 0; idx < len; idx++) {
208
+ const key = keys[idx];
209
+ writeString(state, key);
210
+ writeValue(state, val[key]);
211
+ }
212
+ return;
179
213
  }
180
- return;
181
214
  }
182
215
  }
183
216
  throw new TypeError(`unsupported type: ${val}`);
184
217
  };
185
218
  const createState = () => {
186
- const buf = new ArrayBuffer(CHUNK_SIZE);
219
+ const buf = allocUnsafe(CHUNK_SIZE);
187
220
  return {
188
221
  c: [],
189
222
  b: buf,
190
- v: new DataView(buf),
223
+ v: new DataView(buf.buffer),
191
224
  p: 0,
225
+ l: 0,
192
226
  };
193
227
  };
194
228
  export const encode = (value) => {
195
229
  const state = createState();
196
- const chunks = state.c;
197
230
  writeValue(state, value);
198
- chunks.push(new Uint8Array(state.b, 0, state.p));
199
- let size = 0;
200
- let written = 0;
201
- let len = chunks.length;
202
- let idx;
203
- for (idx = 0; idx < len; idx++) {
204
- size += chunks[idx].byteLength;
205
- }
206
- const u8 = new Uint8Array(size);
207
- for (idx = 0; idx < len; idx++) {
208
- const chunk = chunks[idx];
209
- u8.set(chunk, written);
210
- written += chunk.byteLength;
211
- }
212
- return u8;
213
- };
214
- const isArray = Array.isArray;
215
- const isPlainObject = (v) => {
216
- if (typeof v !== 'object' || v === null) {
217
- return false;
218
- }
219
- const proto = Object.getPrototypeOf(v);
220
- return proto === Object.prototype || proto === null;
231
+ state.c.push(state.b.subarray(0, state.p));
232
+ return concat(state.c, state.l + state.p);
221
233
  };
222
- const compareKeys = (a, b) => {
223
- if (a.length < b.length) {
224
- return -1;
225
- }
226
- else if (b.length < a.length) {
227
- return 1;
228
- }
229
- else {
230
- return a < b ? -1 : 1;
234
+ /** @internal */
235
+ export const getOrderedObjectKeys = (obj) => {
236
+ const keys = Object.keys(obj);
237
+ for (let i = 1, len = keys.length, j = 0; i < len; j = i++) {
238
+ const valA = keys[i];
239
+ // Tuck in undefined value filtering here to avoid extra iterations.
240
+ if (obj[valA] === undefined) {
241
+ // A lot of things are tucked in here xd
242
+ // - Pull the currently last item in the keys array at the current place
243
+ // - Update saved value of array length
244
+ // - Decrease i by 1
245
+ keys[i--] = keys[--len];
246
+ keys.length = len;
247
+ }
248
+ else {
249
+ for (; j >= 0; j--) {
250
+ const valB = keys[j];
251
+ // Note: Don't need to check for equality, keys are always distinct.
252
+ const cmp = valA.length - valB.length || +(valA > valB);
253
+ if (cmp > 0)
254
+ break;
255
+ keys[j + 1] = valB;
256
+ }
257
+ keys[j + 1] = valA;
258
+ }
231
259
  }
260
+ return keys;
232
261
  };
233
262
  //# sourceMappingURL=encode.js.map