1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
/**
* Implements the [Encoding standard](https://encoding.spec.whatwg.org/):
* [TextDecoder](https://encoding.spec.whatwg.org/#interface-textdecoder),
* [TextEncoder](https://encoding.spec.whatwg.org/#interface-textencoder),
* [TextDecoderStream](https://encoding.spec.whatwg.org/#interface-textdecoderstream),
* [TextEncoderStream](https://encoding.spec.whatwg.org/#interface-textencoderstream),
* some [hooks](https://encoding.spec.whatwg.org/#specification-hooks).
*
* ```js
* import { TextDecoder, TextEncoder } from '@exodus/bytes/encoding.js'
* import { TextDecoderStream, TextEncoderStream } from '@exodus/bytes/encoding.js' // Requires Streams
*
* // Hooks for standards
* import { getBOMEncoding, legacyHookDecode, labelToName, normalizeEncoding } from '@exodus/bytes/encoding.js'
* ```
*
* @module @exodus/bytes/encoding.js
*/
/// <reference types="node" />
/**
* Convert an encoding [label](https://encoding.spec.whatwg.org/#names-and-labels) to its name,
* as an ASCII-lowercased string.
*
* If an encoding with that label does not exist, returns `null`.
*
* This is the same as [`decoder.encoding` getter](https://encoding.spec.whatwg.org/#dom-textdecoder-encoding),
* except that it:
* 1. Supports [`replacement` encoding](https://encoding.spec.whatwg.org/#replacement) and its
* [labels](https://encoding.spec.whatwg.org/#ref-for-replacement%E2%91%A1)
* 2. Does not throw for invalid labels and instead returns `null`
*
* It is identical to:
* ```js
* labelToName(label)?.toLowerCase() ?? null
* ```
*
* All encoding names are also valid labels for corresponding encodings.
*
* @param label - The encoding label to normalize
* @returns The normalized encoding name, or null if invalid
*/
export function normalizeEncoding(label: string): string | null;
/**
* Implements [BOM sniff](https://encoding.spec.whatwg.org/#bom-sniff) legacy hook.
*
* Given a `TypedArray` or an `ArrayBuffer` instance `input`, returns either of:
* - `'utf-8'`, if `input` starts with UTF-8 byte order mark.
* - `'utf-16le'`, if `input` starts with UTF-16LE byte order mark.
* - `'utf-16be'`, if `input` starts with UTF-16BE byte order mark.
* - `null` otherwise.
*
* @param input - The bytes to check for BOM
* @returns The encoding ('utf-8', 'utf-16le', 'utf-16be'), or null if no BOM found
*/
export function getBOMEncoding(
input: ArrayBufferLike | ArrayBufferView
): 'utf-8' | 'utf-16le' | 'utf-16be' | null;
/**
* Implements [decode](https://encoding.spec.whatwg.org/#decode) legacy hook.
*
* Given a `TypedArray` or an `ArrayBuffer` instance `input` and an optional `fallbackEncoding`
* encoding [label](https://encoding.spec.whatwg.org/#names-and-labels),
* sniffs encoding from BOM with `fallbackEncoding` fallback and then
* decodes the `input` using that encoding, skipping BOM if it was present.
*
* Notes:
*
* - BOM-sniffed encoding takes precedence over `fallbackEncoding` option per spec.
* Use with care.
* - Always operates in non-fatal [mode](https://encoding.spec.whatwg.org/#textdecoder-error-mode),
* aka replacement. It can convert different byte sequences to equal strings.
*
* This method is similar to the following code, except that it doesn't support encoding labels and
* only expects lowercased encoding name:
*
* ```js
* new TextDecoder(getBOMEncoding(input) ?? fallbackEncoding).decode(input)
* ```
*
* @param input - The bytes to decode
* @param fallbackEncoding - The encoding to use if no BOM detected (default: 'utf-8')
* @returns The decoded string
*/
export function legacyHookDecode(
input: ArrayBufferLike | ArrayBufferView,
fallbackEncoding?: string
): string;
/**
* Implements [get an encoding from a string `label`](https://encoding.spec.whatwg.org/#concept-encoding-get).
*
* Convert an encoding [label](https://encoding.spec.whatwg.org/#names-and-labels) to its name,
* as a case-sensitive string.
*
* If an encoding with that label does not exist, returns `null`.
*
* All encoding names are also valid labels for corresponding encodings.
*
* @param label - The encoding label
* @returns The proper case encoding name, or null if invalid
*/
export function labelToName(label: string): string | null;
/**
* [TextDecoder](https://encoding.spec.whatwg.org/#interface-textdecoder) implementation/polyfill.
*
* Decode bytes to strings according to [WHATWG Encoding](https://encoding.spec.whatwg.org) specification.
*/
export const TextDecoder: typeof globalThis.TextDecoder;
/**
* [TextEncoder](https://encoding.spec.whatwg.org/#interface-textencoder) implementation/polyfill.
*
* Encode strings to UTF-8 bytes according to [WHATWG Encoding](https://encoding.spec.whatwg.org) specification.
*/
export const TextEncoder: typeof globalThis.TextEncoder;
/**
* [TextDecoderStream](https://encoding.spec.whatwg.org/#interface-textdecoderstream) implementation/polyfill.
*
* A [Streams](https://streams.spec.whatwg.org/) wrapper for `TextDecoder`.
*
* Requires [Streams](https://streams.spec.whatwg.org/) to be either supported by the platform or
* [polyfilled](https://npmjs.com/package/web-streams-polyfill).
*/
export const TextDecoderStream: typeof globalThis.TextDecoderStream;
/**
* [TextEncoderStream](https://encoding.spec.whatwg.org/#interface-textencoderstream) implementation/polyfill.
*
* A [Streams](https://streams.spec.whatwg.org/) wrapper for `TextEncoder`.
*
* Requires [Streams](https://streams.spec.whatwg.org/) to be either supported by the platform or
* [polyfilled](https://npmjs.com/package/web-streams-polyfill).
*/
export const TextEncoderStream: typeof globalThis.TextEncoderStream;
|