@exodus/bytes 1.3.0 → 1.4.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 CHANGED
@@ -78,6 +78,13 @@ See [the list of encodings](https://encoding.spec.whatwg.org/#names-and-labels).
78
78
 
79
79
  ### `@exodus/bytes/utf8.js`
80
80
 
81
+ ```js
82
+ import { utf8fromString, utf8toString } from '@exodus/bytes/utf8.js'
83
+
84
+ // loose
85
+ import { utf8fromStringLoose, utf8toStringLoose } from '@exodus/bytes/utf8.js'
86
+ ```
87
+
81
88
  ##### `utf8fromString(str, format = 'uint8')`
82
89
  ##### `utf8fromStringLoose(str, format = 'uint8')`
83
90
  ##### `utf8toString(arr)`
@@ -85,6 +92,13 @@ See [the list of encodings](https://encoding.spec.whatwg.org/#names-and-labels).
85
92
 
86
93
  ### `@exodus/bytes/utf16.js`
87
94
 
95
+ ```js
96
+ import { utf16fromString, utf16toString } from '@exodus/bytes/utf16.js'
97
+
98
+ // loose
99
+ import { utf16fromStringLoose, utf16toStringLoose } from '@exodus/bytes/utf16.js'
100
+ ```
101
+
88
102
  ##### `utf16fromString(str, format = 'uint16')`
89
103
  ##### `utf16fromStringLoose(str, format = 'uint16')`
90
104
  ##### `utf16toString(arr, 'uint16')`
@@ -92,21 +106,26 @@ See [the list of encodings](https://encoding.spec.whatwg.org/#names-and-labels).
92
106
 
93
107
  ### `@exodus/bytes/single-byte.js`
94
108
 
95
- ##### `createSinglebyteDecoder(encoding, loose = false)`
96
-
97
- Create a decoder for a supported one-byte `encoding`.
98
-
99
- Returns a function `decode(arr)` that decodes bytes to a string.
109
+ ```js
110
+ import { createSinglebyteDecoder } from '@exodus/bytes/single-byte.js'
111
+ import { windows1252toString } from '@exodus/bytes/single-byte.js'
112
+ ```
100
113
 
101
- ### `@exodus/bytes/multi-byte.js`
114
+ Decode the legacy single-byte encodings according to the [Encoding standard](https://encoding.spec.whatwg.org/)
115
+ ([§9](https://encoding.spec.whatwg.org/#legacy-single-byte-encodings) and
116
+ [§14.5](https://encoding.spec.whatwg.org/#x-user-defined)).
102
117
 
103
- ##### `createMultibyteDecoder(encoding, loose = false)`
118
+ Supports all single-byte encodings listed in the standard:
119
+ `ibm866`, `iso-8859-2`, `iso-8859-3`, `iso-8859-4`, `iso-8859-5`, `iso-8859-6`, `iso-8859-7`, `iso-8859-8`,
120
+ `iso-8859-8-i`, `iso-8859-10`, `iso-8859-13`, `iso-8859-14`, `iso-8859-15`, `iso-8859-16`, `koi8-r`, `koi8-u`,
121
+ `macintosh`, `windows-874`, `windows-1250`, `windows-1251`, `windows-1252`, `windows-1253`, `windows-1254`,
122
+ `windows-1255`, `windows-1256`, `windows-1257`, `windows-1258`, `x-mac-cyrillic` and `x-user-defined`.
104
123
 
105
- Create a decoder for a supported legacy multi-byte `encoding`.
124
+ ##### `createSinglebyteDecoder(encoding, loose = false)`
106
125
 
107
- Returns a function `decode(arr, stream = false)` that decodes bytes to a string.
126
+ Create a decoder for a supported one-byte `encoding`, given it's lowercased name `encoding`.
108
127
 
109
- That function will have state while `stream = true` is used.
128
+ Returns a function `decode(arr)` that decodes bytes to a string.
110
129
 
111
130
  ##### `windows1252toString(arr)`
112
131
 
@@ -116,61 +135,132 @@ Also supports `ascii` and `latin-1` as those are strict subsets of `windows-1252
116
135
 
117
136
  There is no loose variant for this encoding, all bytes can be decoded.
118
137
 
119
- Same as `windows1252toString = createSinglebyteDecoder('windows-1252')`.
138
+ Same as:
139
+ ```js
140
+ const windows1252toString = createSinglebyteDecoder('windows-1252')
141
+ ```
142
+
143
+ ### `@exodus/bytes/multi-byte.js`
144
+
145
+ ```js
146
+ import { createMultibyteDecoder } from '@exodus/bytes/multi-byte.js'
147
+ ```
148
+
149
+ Decode the legacy multi-byte encodings according to the [Encoding standard](https://encoding.spec.whatwg.org/)
150
+ ([§10](https://encoding.spec.whatwg.org/#legacy-multi-byte-chinese-(simplified)-encodings),
151
+ [§11](https://encoding.spec.whatwg.org/#legacy-multi-byte-chinese-(traditional)-encodings),
152
+ [§12](https://encoding.spec.whatwg.org/#legacy-multi-byte-japanese-encodings),
153
+ [§13](https://encoding.spec.whatwg.org/#legacy-multi-byte-korean-encodings)).
154
+
155
+ Supports all legacy multi-byte encodings listed in the standard:
156
+ `gbk`, `gb18030`, `big5`, `euc-jp`, `iso-2022-jp`, `shift_jis`, `euc-kr`.
157
+
158
+ ##### `createMultibyteDecoder(encoding, loose = false)`
159
+
160
+ Create a decoder for a supported legacy multi-byte `encoding`, given it's lowercased name `encoding`.
161
+
162
+ Returns a function `decode(arr, stream = false)` that decodes bytes to a string.
163
+
164
+ That function will have state while `stream = true` is used.
120
165
 
121
166
  ### `@exodus/bytes/bigint.js`
122
167
 
168
+ ```js
169
+ import { fromBigInt, toBigInt } from '@exodus/bytes/bigint.js'
170
+ ```
171
+
123
172
  ##### `fromBigInt(bigint, { length, format = 'uint8' })`
124
173
  ##### `toBigInt(arr)`
125
174
 
126
175
  ### `@exodus/bytes/hex.js`
127
176
 
128
- ##### `toHex(arr)`
177
+ ```js
178
+ import { fromHex, toHex } from '@exodus/bytes/hex.js'
179
+ ```
180
+
129
181
  ##### `fromHex(string)`
182
+ ##### `toHex(arr)`
130
183
 
131
184
  ### `@exodus/bytes/base64.js`
132
185
 
133
- ##### `toBase64(arr, { padding = true })`
134
- ##### `toBase64url(arr, { padding = false })`
186
+ ```js
187
+ import { fromBase64, toBase64 } from '@exodus/bytes/base64.js'
188
+ import { fromBase64url, toBase64url } from '@exodus/bytes/base64.js'
189
+ import { fromBase64any } from '@exodus/bytes/base64.js'
190
+ ```
191
+
135
192
  ##### `fromBase64(str, { format = 'uint8', padding = 'both' })`
136
193
  ##### `fromBase64url(str, { format = 'uint8', padding = false })`
137
194
  ##### `fromBase64any(str, { format = 'uint8', padding = 'both' })`
195
+ ##### `toBase64(arr, { padding = true })`
196
+ ##### `toBase64url(arr, { padding = false })`
138
197
 
139
198
  ### `@exodus/bytes/base32.js`
140
199
 
141
- ##### `toBase32(arr, { padding = false })`
142
- ##### `toBase32hex(arr, { padding = false })`
200
+ ```js
201
+ import { fromBase32, toBase32 } from '@exodus/bytes/base32.js'
202
+ import { fromBase32hex, toBase32hex } from '@exodus/bytes/base32.js'
203
+ ```
204
+
143
205
  ##### `fromBase32(str, { format = 'uint8', padding = 'both' })`
144
206
  ##### `fromBase32hex(str, { format = 'uint8', padding = 'both' })`
207
+ ##### `toBase32(arr, { padding = false })`
208
+ ##### `toBase32hex(arr, { padding = false })`
145
209
 
146
210
  ### `@exodus/bytes/bech32.js`
147
211
 
212
+ ```js
213
+ import { fromBech32, toBech32 } from '@exodus/bytes/bech32.js'
214
+ import { fromBech32m, toBech32m } from '@exodus/bytes/base32.js'
215
+ import { getPrefix } from '@exodus/bytes/base32.js'
216
+ ```
217
+
148
218
  ##### `getPrefix(str, limit = 90)`
149
- ##### `toBech32(prefix, bytes, limit = 90)`
219
+
150
220
  ##### `fromBech32(str, limit = 90)`
151
- ##### `toBech32m(prefix, bytes, limit = 90)`
221
+ ##### `toBech32(prefix, bytes, limit = 90)`
222
+
152
223
  ##### `fromBech32m(str, limit = 90)`
224
+ ##### `toBech32m(prefix, bytes, limit = 90)`
153
225
 
154
226
  ### `@exodus/bytes/base58.js`
155
227
 
156
- ##### `toBase58(arr)`
228
+ ```js
229
+ import { fromBase58, toBase58 } from '@exodus/bytes/base58.js'
230
+ import { fromBase58xrp, toBase58xrp } from '@exodus/bytes/base58.js'
231
+ ```
232
+
157
233
  ##### `fromBase58(str, format = 'uint8')`
234
+ ##### `toBase58(arr)`
158
235
 
159
- ##### `toBase58xrp(arr)`
160
236
  ##### `fromBase58xrp(str, format = 'uint8')`
237
+ ##### `toBase58xrp(arr)`
161
238
 
162
239
  ### `@exodus/bytes/base58check.js`
163
240
 
241
+ ```js
242
+ import { fromBase58check, toBase58check } from '@exodus/bytes/base58check.js'
243
+ import { fromBase58checkSync, toBase58checkSync } from '@exodus/bytes/base58check.js'
244
+ import { makeBase58check } from '@exodus/bytes/base58check.js'
245
+ ```
246
+
164
247
  On non-Node.js, requires peer dependency [@exodus/crypto](https://www.npmjs.com/package/@exodus/crypto) to be installed.
165
248
 
166
- ##### `async toBase58check(arr)`
167
- ##### `toBase58checkSync(arr)`
168
249
  ##### `async fromBase58check(str, format = 'uint8')`
250
+ ##### `async toBase58check(arr)`
169
251
  ##### `fromBase58checkSync(str, format = 'uint8')`
252
+ ##### `toBase58checkSync(arr)`
170
253
  ##### `makeBase58check(hashAlgo, hashAlgoSync)`
171
254
 
172
255
  ### `@exodus/bytes/wif.js`
173
256
 
257
+ ```js
258
+ import { fromWifString, toWifString } from '@exodus/bytes/wif.js'
259
+ import { fromWifStringSync, toWifStringSync } from '@exodus/bytes/wif.js'
260
+ ```
261
+
262
+ On non-Node.js, requires peer dependency [@exodus/crypto](https://www.npmjs.com/package/@exodus/crypto) to be installed.
263
+
174
264
  ##### `async fromWifString(string, version)`
175
265
  ##### `fromWifStringSync(string, version)`
176
266
  ##### `async toWifString({ version, privateKey, compressed })`
@@ -178,18 +268,18 @@ On non-Node.js, requires peer dependency [@exodus/crypto](https://www.npmjs.com/
178
268
 
179
269
  ### `@exodus/bytes/encoding.js`
180
270
 
181
- Implements the [Encoding standard](https://encoding.spec.whatwg.org/):
182
- [TextDecoder](https://encoding.spec.whatwg.org/#interface-textdecoder),
183
- [TextEncoder](https://encoding.spec.whatwg.org/#interface-textdecoder),
184
- some [hooks](https://encoding.spec.whatwg.org/#specification-hooks) (see below).
185
-
186
271
  ```js
187
- import { TextDecoder, TextDecoder } from '@exodus/bytes/encoding.js'
272
+ import { TextDecoder, TextEncoder } from '@exodus/bytes/encoding.js'
188
273
 
189
274
  // Hooks for standards
190
275
  import { getBOMEncoding, legacyHookDecode, labelToName, normalizeEncoding } from '@exodus/bytes/encoding.js'
191
276
  ```
192
277
 
278
+ Implements the [Encoding standard](https://encoding.spec.whatwg.org/):
279
+ [TextDecoder](https://encoding.spec.whatwg.org/#interface-textdecoder),
280
+ [TextEncoder](https://encoding.spec.whatwg.org/#interface-textdecoder),
281
+ some [hooks](https://encoding.spec.whatwg.org/#specification-hooks) (see below).
282
+
193
283
  #### `new TextDecoder(label = 'utf-8', { fatal = false, ignoreBOM = false })`
194
284
 
195
285
  [TextDecoder](https://encoding.spec.whatwg.org/#interface-textdecoder) implementation/polyfill.
@@ -265,7 +355,7 @@ new TextDecoder(getBOMEncoding(input) ?? fallbackEncoding).decode(input)
265
355
  ### `@exodus/bytes/encoding-lite.js`
266
356
 
267
357
  ```js
268
- import { TextDecoder, TextDecoder } from '@exodus/bytes/encoding-lite.js'
358
+ import { TextDecoder, TextEncoder } from '@exodus/bytes/encoding-lite.js'
269
359
 
270
360
  // Hooks for standards
271
361
  import { getBOMEncoding, legacyHookDecode, labelToName, normalizeEncoding } from '@exodus/bytes/encoding-lite.js'
@@ -106,7 +106,7 @@ function decodePartTemplates(a, start, end, m) {
106
106
 
107
107
  const decodePart = isHermes ? decodePartTemplates : decodePartAddition
108
108
  export function decode2string(arr, start, end, m) {
109
- if (start - end > 30_000) {
109
+ if (end - start > 30_000) {
110
110
  // Limit concatenation to avoid excessive GC
111
111
  // Thresholds checked on Hermes for toHex
112
112
  const concat = []
@@ -47,11 +47,18 @@ export function normalizeEncoding(label) {
47
47
 
48
48
  const define = (obj, key, value) => Object.defineProperty(obj, key, { value, writable: false })
49
49
 
50
+ function isAnyArrayBuffer(x) {
51
+ if (x instanceof ArrayBuffer) return true
52
+ if (globalThis.SharedArrayBuffer && x instanceof SharedArrayBuffer) return true
53
+ if (!x || typeof x.byteLength !== 'number') return false
54
+ const s = Object.prototype.toString.call(x)
55
+ return s === '[object ArrayBuffer]' || s === '[object SharedArrayBuffer]'
56
+ }
57
+
50
58
  const fromSource = (x) => {
51
59
  if (x instanceof Uint8Array) return x
52
- if (x instanceof ArrayBuffer) return new Uint8Array(x)
53
60
  if (ArrayBuffer.isView(x)) return new Uint8Array(x.buffer, x.byteOffset, x.byteLength)
54
- if (globalThis.SharedArrayBuffer && x instanceof SharedArrayBuffer) return new Uint8Array(x)
61
+ if (isAnyArrayBuffer(x)) return new Uint8Array(x)
55
62
  throw new TypeError('Argument must be a SharedArrayBuffer, ArrayBuffer or ArrayBufferView')
56
63
  }
57
64
 
@@ -295,6 +302,7 @@ const uppercasePrefixes = new Set(['utf', 'iso', 'koi', 'euc', 'ibm', 'gbk'])
295
302
  // https://encoding.spec.whatwg.org/#names-and-labels
296
303
  export function labelToName(label) {
297
304
  const enc = normalizeEncoding(label)
305
+ if (enc === 'utf-8') return 'UTF-8' // fast path
298
306
  if (!enc) return enc
299
307
  if (uppercasePrefixes.has(enc.slice(0, 3))) return enc.toUpperCase()
300
308
  if (enc === 'big5') return 'Big5'
@@ -13,7 +13,7 @@ export const E_STRICT = 'Input is not well-formed for this encoding'
13
13
  const REP = 0xff_fd
14
14
  const mappers = {
15
15
  // https://encoding.spec.whatwg.org/#euc-kr-decoder
16
- 'euc-kr': () => {
16
+ 'euc-kr': (err) => {
17
17
  const euc = getTable('euc-kr')
18
18
  let lead = 0
19
19
 
@@ -24,25 +24,24 @@ const mappers = {
24
24
  lead = 0
25
25
  if (cp !== undefined && cp !== REP) return cp
26
26
  if (b < 128) pushback.push(b)
27
- return -2
27
+ return err()
28
28
  }
29
29
 
30
30
  if (b < 128) return b
31
- if (b < 0x81 || b === 0xff) return -2
31
+ if (b < 0x81 || b === 0xff) return err()
32
32
  lead = b
33
- return -1
34
33
  }
35
34
 
36
35
  const eof = () => {
37
36
  if (!lead) return null
38
37
  lead = 0
39
- return -2
38
+ return err()
40
39
  }
41
40
 
42
41
  return { bytes, eof, pushback }
43
42
  },
44
43
  // https://encoding.spec.whatwg.org/#euc-jp-decoder
45
- 'euc-jp': () => {
44
+ 'euc-jp': (err) => {
46
45
  const jis0208 = getTable('jis0208')
47
46
  const jis0212 = getTable('jis0212')
48
47
  let j12 = false
@@ -58,7 +57,7 @@ const mappers = {
58
57
  if (lead === 0x8f && b >= 0xa1 && b <= 0xfe) {
59
58
  j12 = true
60
59
  lead = b
61
- return -1
60
+ return
62
61
  }
63
62
 
64
63
  if (lead) {
@@ -71,27 +70,26 @@ const mappers = {
71
70
  j12 = false
72
71
  if (cp !== undefined && cp !== REP) return cp
73
72
  if (b < 128) pushback.push(b)
74
- return -2
73
+ return err()
75
74
  }
76
75
 
77
76
  if (b < 128) return b
78
- if ((b < 0xa1 && b !== 0x8e && b !== 0x8f) || b === 0xff) return -2
77
+ if ((b < 0xa1 && b !== 0x8e && b !== 0x8f) || b === 0xff) return err()
79
78
  lead = b
80
- return -1
81
79
  }
82
80
 
83
81
  // eslint-disable-next-line sonarjs/no-identical-functions
84
82
  const eof = () => {
85
83
  if (!lead) return null
86
84
  lead = 0
87
- return -2
85
+ return err()
88
86
  }
89
87
 
90
88
  return { bytes, eof, pushback }
91
89
  },
92
90
  // https://encoding.spec.whatwg.org/#iso-2022-jp-decoder
93
91
  // Per-letter of the spec, don't shortcut on state changes on EOF. Some code is regrouped but preserving the logic
94
- 'iso-2022-jp': () => {
92
+ 'iso-2022-jp': (err) => {
95
93
  const jis0208 = getTable('jis0208')
96
94
  const EOF = -1
97
95
  let dState = 1
@@ -105,7 +103,7 @@ const mappers = {
105
103
  if (b === EOF) return null
106
104
  if (b === 0x1b) {
107
105
  dState = 6 // escape start
108
- return -1
106
+ return
109
107
  }
110
108
  }
111
109
 
@@ -120,49 +118,46 @@ const mappers = {
120
118
  }
121
119
 
122
120
  if (b <= 0x7f && b !== 0x0e && b !== 0x0f) return b
123
- return -2
121
+ return err()
124
122
  case 3:
125
123
  // Katakana
126
124
  out = false
127
125
  if (b >= 0x21 && b <= 0x5f) return 0xff_40 + b
128
- return -2
126
+ return err()
129
127
  case 4:
130
128
  // Leading byte
131
129
  out = false
132
- if ((b >= 0x21) & (b <= 0x7e)) {
133
- lead = b
134
- dState = 5
135
- return -1
136
- }
137
-
138
- return -2
130
+ if (b < 0x21 || b > 0x7e) return err()
131
+ lead = b
132
+ dState = 5
133
+ return
139
134
  case 5:
140
135
  // Trailing byte
141
136
  out = false
142
137
  if (b === 0x1b) {
143
138
  dState = 6 // escape start
144
- return -2
139
+ return err()
145
140
  }
146
141
 
147
142
  dState = 4
148
143
  if (b >= 0x21 && b <= 0x7e) {
149
144
  const cp = jis0208[(lead - 0x21) * 94 + b - 0x21]
150
- return cp !== undefined && cp !== REP ? cp : -2
145
+ if (cp !== undefined && cp !== REP) return cp
151
146
  }
152
147
 
153
- return -2
148
+ return err()
154
149
  case 6:
155
150
  // Escape start
156
151
  if (b === 0x24 || b === 0x28) {
157
152
  lead = b
158
153
  dState = 7
159
- return -1
154
+ return
160
155
  }
161
156
 
162
157
  out = false
163
158
  dState = oState
164
159
  if (b !== EOF) pushback.push(b)
165
- return -2
160
+ return err()
166
161
  case 7: {
167
162
  // Escape
168
163
  const l = lead
@@ -185,14 +180,14 @@ const mappers = {
185
180
  dState = oState = s
186
181
  const output = out
187
182
  out = true
188
- return output ? -2 : -1
183
+ return output ? err() : undefined
189
184
  }
190
185
 
191
186
  out = false
192
187
  dState = oState
193
188
  if (b !== EOF) pushback.push(b)
194
189
  pushback.push(l)
195
- return -2
190
+ return err()
196
191
  }
197
192
  }
198
193
  }
@@ -202,7 +197,7 @@ const mappers = {
202
197
  return { bytes, eof, pushback }
203
198
  },
204
199
  // https://encoding.spec.whatwg.org/#shift_jis-decoder
205
- shift_jis: () => {
200
+ shift_jis: (err) => {
206
201
  const jis0208 = getTable('jis0208')
207
202
  let lead = 0
208
203
 
@@ -219,29 +214,28 @@ const mappers = {
219
214
  }
220
215
 
221
216
  if (b < 128) pushback.push(b)
222
- return -2
217
+ return err()
223
218
  }
224
219
 
225
220
  if (b <= 0x80) return b // 0x80 is allowed
226
221
  if (b >= 0xa1 && b <= 0xdf) return 0xff_61 - 0xa1 + b
227
- if (b < 0x81 || (b > 0x9f && b < 0xe0) || b > 0xfc) return -2
222
+ if (b < 0x81 || (b > 0x9f && b < 0xe0) || b > 0xfc) return err()
228
223
  lead = b
229
- return -1
230
224
  }
231
225
 
232
226
  // eslint-disable-next-line sonarjs/no-identical-functions
233
227
  const eof = () => {
234
228
  if (!lead) return null
235
229
  lead = 0 // this clears state completely on EOF
236
- return -2
230
+ return err()
237
231
  }
238
232
 
239
233
  return { bytes, eof, pushback }
240
234
  },
241
235
  // https://encoding.spec.whatwg.org/#gbk-decoder
242
- gbk: () => mappers.gb18030(), // 10.1.1. GBK’s decoder is gb18030’s decoder
236
+ gbk: (err) => mappers.gb18030(err), // 10.1.1. GBK’s decoder is gb18030’s decoder
243
237
  // https://encoding.spec.whatwg.org/#gb18030-decoder
244
- gb18030: () => {
238
+ gb18030: (err) => {
245
239
  const gb18030 = getTable('gb18030')
246
240
  const gb18030r = getTable('gb18030-ranges')
247
241
  let g1 = 0, g2 = 0, g3 = 0 // prettier-ignore
@@ -264,30 +258,30 @@ const mappers = {
264
258
  if (b < 0x30 || b > 0x39) {
265
259
  pushback.push(b, g3, g2)
266
260
  g1 = g2 = g3 = 0
267
- return -2
261
+ return err()
268
262
  }
269
263
 
270
264
  const cp = index((g1 - 0x81) * 12_600 + (g2 - 0x30) * 1260 + (g3 - 0x81) * 10 + b - 0x30)
271
265
  g1 = g2 = g3 = 0
272
266
  if (cp !== undefined) return cp // Can validly return replacement
273
- return -2
267
+ return err()
274
268
  }
275
269
 
276
270
  if (g2) {
277
271
  if (b >= 0x81 && b <= 0xfe) {
278
272
  g3 = b
279
- return -1
273
+ return
280
274
  }
281
275
 
282
276
  pushback.push(b, g2)
283
277
  g1 = g2 = 0
284
- return -2
278
+ return err()
285
279
  }
286
280
 
287
281
  if (g1) {
288
282
  if (b >= 0x30 && b <= 0x39) {
289
283
  g2 = b
290
- return -1
284
+ return
291
285
  }
292
286
 
293
287
  let cp
@@ -298,20 +292,19 @@ const mappers = {
298
292
  g1 = 0
299
293
  if (cp !== undefined && cp !== REP) return cp
300
294
  if (b < 128) pushback.push(b)
301
- return -2
295
+ return err()
302
296
  }
303
297
 
304
298
  if (b < 128) return b
305
299
  if (b === 0x80) return 0x20_ac
306
- if (b === 0xff) return -2
300
+ if (b === 0xff) return err()
307
301
  g1 = b
308
- return -1
309
302
  }
310
303
 
311
304
  const eof = () => {
312
305
  if (!g1 && !g2 && !g3) return null
313
306
  g1 = g2 = g3 = 0
314
- return -2
307
+ return err()
315
308
  }
316
309
 
317
310
  return { bytes, eof, pushback }
@@ -329,7 +322,7 @@ export function multibyteDecoder(enc, loose = false) {
329
322
  const asciiSuperset = isAsciiSuperset(enc)
330
323
  return (arr, stream = false) => {
331
324
  const onErr = loose
332
- ? () => '\uFFFD'
325
+ ? () => REP
333
326
  : () => {
334
327
  mapper.pushback.length = 0 // the queue is cleared on returning an error
335
328
  // The correct way per spec seems to be not destoying the decoder state in stream mode, even when fatal
@@ -346,7 +339,7 @@ export function multibyteDecoder(enc, loose = false) {
346
339
  if (res.length === arr.length) return res // ascii
347
340
  }
348
341
 
349
- if (!mapper) mapper = mappers[enc]()
342
+ if (!mapper) mapper = mappers[enc](onErr)
350
343
  const { bytes, eof, pushback } = mapper
351
344
  let i = res.length
352
345
 
@@ -354,11 +347,8 @@ export function multibyteDecoder(enc, loose = false) {
354
347
  // Same as the full loop, but without EOF handling
355
348
  while (i < length || pushback.length > 0) {
356
349
  const c = bytes(pushback.length > 0 ? pushback.pop() : arr[i++])
357
- if (c >= 0) {
358
- res += String.fromCodePoint(c) // gb18030 returns codepoints above 0xFFFF from ranges
359
- } else if (c === -2) {
360
- res += onErr()
361
- }
350
+ if (c === undefined) continue // consuming
351
+ res += String.fromCodePoint(c) // gb18030 returns codepoints above 0xFFFF from ranges
362
352
  }
363
353
 
364
354
  // Then, dump EOF. This needs the same loop as the characters can be pushed back
@@ -368,12 +358,8 @@ export function multibyteDecoder(enc, loose = false) {
368
358
  const isEOF = i === length && pushback.length === 0
369
359
  const c = isEOF ? eof() : bytes(pushback.length > 0 ? pushback.pop() : arr[i++])
370
360
  if (isEOF && c === null) break // clean exit
371
- if (c === -1) continue // consuming
372
- if (c === -2) {
373
- res += onErr()
374
- } else {
375
- res += String.fromCodePoint(c) // gb18030 returns codepoints above 0xFFFF from ranges
376
- }
361
+ if (c === undefined) continue // consuming
362
+ res += String.fromCodePoint(c) // gb18030 returns codepoints above 0xFFFF from ranges
377
363
  }
378
364
  }
379
365
 
@@ -392,12 +378,10 @@ function big5decoder(loose) {
392
378
  // Input is assumed to be typechecked already
393
379
  let lead = 0
394
380
  let big5
395
- const pushback = []
396
381
  return (arr, stream = false) => {
397
382
  const onErr = loose
398
383
  ? () => '\uFFFD'
399
384
  : () => {
400
- pushback.length = 0 // the queue is cleared on returning an error
401
385
  // Lead is always already cleared before throwing
402
386
  throw new TypeError(E_STRICT)
403
387
  }
@@ -410,8 +394,8 @@ function big5decoder(loose) {
410
394
  }
411
395
 
412
396
  if (!big5) big5 = getTable('big5')
413
- for (let i = res.length; i < length || pushback.length > 0; ) {
414
- const b = pushback.length > 0 ? pushback.pop() : arr[i++]
397
+ for (let i = res.length; i < length; i++) {
398
+ const b = arr[i]
415
399
  if (lead) {
416
400
  let cp
417
401
  if ((b >= 0x40 && b <= 0x7e) || (b >= 0xa1 && b !== 0xff)) {
@@ -423,7 +407,8 @@ function big5decoder(loose) {
423
407
  res += cp // strings
424
408
  } else {
425
409
  res += onErr()
426
- if (b < 128) pushback.push(b)
410
+ // same as pushing it back: lead is cleared, pushed back can't contain more than 1 byte
411
+ if (b < 128) res += String.fromCharCode(b)
427
412
  }
428
413
  } else if (b < 128) {
429
414
  res += String.fromCharCode(b)
@@ -434,13 +419,10 @@ function big5decoder(loose) {
434
419
  }
435
420
  }
436
421
 
437
- if (!stream) {
422
+ if (!stream && lead) {
438
423
  // Destroy decoder state
439
- pushback.length = 0
440
- if (lead) {
441
- lead = 0
442
- res += onErr()
443
- }
424
+ lead = 0
425
+ res += onErr()
444
426
  }
445
427
 
446
428
  return res
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/bytes",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Various operations on Uint8Array data",
5
5
  "scripts": {
6
6
  "lint": "eslint .",
package/wif.js CHANGED
@@ -1,4 +1,4 @@
1
- import { toBase58checkSync, fromBase58checkSync } from './base58check.js'
1
+ import { toBase58checkSync, fromBase58checkSync } from '@exodus/bytes/base58check.js'
2
2
  import { assertUint8 } from './assert.js'
3
3
 
4
4
  // Mostly matches npmjs.com/wif, but with extra checks + using our base58check