@sie-js/wbxml 1.0.0 → 1.1.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.
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { main } from '../cli.js';
3
+
4
+ await main('xml2wbxml');
package/src/cli.ts ADDED
@@ -0,0 +1,322 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { readFile, writeFile } from 'node:fs/promises';
3
+ import { parseArgs, type ParseArgsConfig } from 'node:util';
4
+ import {
5
+ wbxml2xml,
6
+ xml2wbxml,
7
+ WBXML_GEN_MODES,
8
+ WBXML_VERSIONS,
9
+ WBXMLOptionError,
10
+ type WBXMLCharset,
11
+ type WBXMLGenMode,
12
+ type WBXMLLang,
13
+ type WBXMLVersion,
14
+ } from './index.js';
15
+
16
+ class UsageError extends Error {}
17
+
18
+ const LANG_DESCRIPTIONS: Record<WBXMLLang, string> = {
19
+ WML10: 'WML 1.0',
20
+ WML11: 'WML 1.1',
21
+ WML12: 'WML 1.2',
22
+ WML13: 'WML 1.3',
23
+ WTA10: 'WTA 1.0',
24
+ WTAWML12: 'WTAWML 1.2',
25
+ CHANNEL11: 'CHANNEL 1.1',
26
+ CHANNEL12: 'CHANNEL 1.2',
27
+ SI10: 'SI 1.0 (Service Indication)',
28
+ SL10: 'SL 1.0 (Service Loading)',
29
+ CO10: 'CO 1.0 (Cache Operation)',
30
+ PROV10: 'PROV 1.0 (OMA Provisioning)',
31
+ EMN10: 'EMN 1.0 (E-Mail Notification)',
32
+ DRMREL10: 'DRMREL 1.0 (DRM Rights Expression)',
33
+ OTA: 'OTA Settings (Nokia/Ericsson)',
34
+ SYNCML10: 'SyncML 1.0',
35
+ DEVINF10: 'SyncML DevInf 1.0',
36
+ SYNCML11: 'SyncML 1.1',
37
+ DEVINF11: 'SyncML DevInf 1.1',
38
+ METINF11: 'SyncML MetInf 1.1',
39
+ SYNCML12: 'SyncML 1.2',
40
+ DEVINF12: 'SyncML DevInf 1.2',
41
+ METINF12: 'SyncML MetInf 1.2',
42
+ DMDDF12: 'SyncML DM DDF 1.2',
43
+ CSP11: 'Wireless Village CSP 1.1',
44
+ CSP12: 'Wireless Village CSP 1.2',
45
+ AIRSYNC: 'Microsoft AirSync (SynCE namespaces)',
46
+ ACTIVESYNC: 'Microsoft ActiveSync (original namespaces)',
47
+ CONML: 'Nokia ConML',
48
+ };
49
+
50
+ const CHARSET_DESCRIPTIONS: Record<WBXMLCharset, string> = {
51
+ 'ASCII': 'US ASCII',
52
+ 'ISO-8859-1': 'Western European',
53
+ 'ISO-8859-2': 'Central European',
54
+ 'ISO-8859-3': 'South European',
55
+ 'ISO-8859-4': 'North European',
56
+ 'ISO-8859-5': 'Latin/Cyrillic',
57
+ 'ISO-8859-6': 'Latin/Arabic',
58
+ 'ISO-8859-7': 'Latin/Greek',
59
+ 'ISO-8859-8': 'Latin/Hebrew',
60
+ 'ISO-8859-9': 'Latin/Turkish',
61
+ 'ISO-10646-UCS-2': 'UCS-2',
62
+ 'SHIFT_JIS': 'Shift JIS (Japanese)',
63
+ 'BIG5': 'Big5 (Chinese)',
64
+ 'UTF-8': 'UTF-8',
65
+ 'UTF-16': 'UTF-16',
66
+ };
67
+
68
+ function getPackageVersion(): string {
69
+ const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));
70
+ return pkg.version;
71
+ }
72
+
73
+ function formatList(descriptions: Record<string, string>): string {
74
+ const width = Math.max(...Object.keys(descriptions).map((k) => k.length));
75
+ return Object.entries(descriptions)
76
+ .map(([name, descr]) => ` ${name.padEnd(width)} ${descr}`)
77
+ .join('\n');
78
+ }
79
+
80
+ // libwbxml tools accept the generation mode as a number.
81
+ function parseMode(value: string | undefined): string | undefined {
82
+ if (value !== undefined && /^\d+$/.test(value))
83
+ return WBXML_GEN_MODES[Number(value)] ?? value;
84
+ return value;
85
+ }
86
+
87
+ async function readInput(file: string | undefined): Promise<Buffer> {
88
+ if (file !== undefined && file !== '-')
89
+ return readFile(file);
90
+ if (process.stdin.isTTY)
91
+ throw new UsageError('no input file given and stdin is a terminal');
92
+ const chunks: Buffer[] = [];
93
+ for await (const chunk of process.stdin)
94
+ chunks.push(chunk);
95
+ return Buffer.concat(chunks);
96
+ }
97
+
98
+ async function writeOutput(file: string | undefined, data: string | Uint8Array): Promise<void> {
99
+ if (file !== undefined && file !== '-')
100
+ return writeFile(file, data);
101
+ await new Promise<void>((resolve, reject) => {
102
+ process.stdout.write(data, (err) => err ? reject(err) : resolve());
103
+ });
104
+ }
105
+
106
+ function parse<T extends NonNullable<ParseArgsConfig['options']>>(argv: string[], options: T) {
107
+ try {
108
+ return parseArgs({ args: argv, options, allowPositionals: true, strict: true });
109
+ } catch (e) {
110
+ throw new UsageError((e as Error).message);
111
+ }
112
+ }
113
+
114
+ function getSingleInput(positionals: string[]): string | undefined {
115
+ if (positionals.length > 1)
116
+ throw new UsageError(`too many input files: ${positionals.join(' ')}`);
117
+ return positionals[0];
118
+ }
119
+
120
+ const WBXML2XML_HELP = `Usage: wbxml2xml [options] [input.wbxml]
121
+
122
+ Convert a WBXML document to XML.
123
+ Reads from stdin when input is omitted or '-'; writes to stdout unless -o is given.
124
+
125
+ Options:
126
+ -o, --output <file> Output file ('-' for stdout, default)
127
+ -m, --mode <mode> Generation mode (default: indent):
128
+ 0, compact Compact generation
129
+ 1, indent Indent generation
130
+ 2, canonical Canonical generation
131
+ -i, --indent <n> Indent delta for the indent mode (default: 0)
132
+ -k, --keep-whitespace Keep ignorable whitespaces
133
+ -l, --lang <lang> Force language type of the document (see --list-langs)
134
+ -c, --charset <charset> Charset to use if the document does not specify one
135
+ (see --list-charsets)
136
+ --list-langs List supported languages
137
+ --list-charsets List supported charsets
138
+ -h, --help Show this help
139
+ -V, --version Show version
140
+
141
+ Examples:
142
+ wbxml2xml -o output.xml input.wbxml
143
+ wbxml2xml -i 4 -l CSP12 input.wbxml > output.xml
144
+ cat input.wbxml | wbxml2xml -m compact
145
+ `;
146
+
147
+ const XML2WBXML_HELP = `Usage: xml2wbxml [options] [input.xml]
148
+
149
+ Convert an XML document to WBXML.
150
+ Reads from stdin when input is omitted or '-'; writes to stdout unless -o is given.
151
+
152
+ Options:
153
+ -o, --output <file> Output file ('-' for stdout)
154
+ -v, --wbxml-version <ver> WBXML version of the output document: ${WBXML_VERSIONS.join(', ')} (default: 1.3)
155
+ -k, --keep-whitespace Keep ignorable whitespaces
156
+ -n, --no-string-table Do not generate the string table
157
+ -a, --anonymous Anonymous format: do not include any format
158
+ information (public ID or DTD)
159
+ -h, --help Show this help
160
+ -V, --version Show version
161
+
162
+ Examples:
163
+ xml2wbxml -o output.wbxml input.xml
164
+ xml2wbxml -k -n -v 1.1 -o output.wbxml input.xml
165
+ xml2wbxml input.xml | xxd
166
+ `;
167
+
168
+ const WBXML_HELP = `Usage: wbxml <command> [options] [input]
169
+
170
+ Commands:
171
+ decode, wbxml2xml Convert WBXML to XML (see 'wbxml decode --help')
172
+ encode, xml2wbxml Convert XML to WBXML (see 'wbxml encode --help')
173
+ langs List supported languages
174
+ charsets List supported charsets
175
+
176
+ Options:
177
+ -h, --help Show this help
178
+ -V, --version Show version
179
+ `;
180
+
181
+ async function runWbxml2xml(argv: string[]): Promise<void> {
182
+ const { values, positionals } = parse(argv, {
183
+ 'output': { type: 'string', short: 'o' },
184
+ 'mode': { type: 'string', short: 'm' },
185
+ 'indent': { type: 'string', short: 'i' },
186
+ 'keep-whitespace': { type: 'boolean', short: 'k' },
187
+ 'lang': { type: 'string', short: 'l' },
188
+ 'charset': { type: 'string', short: 'c' },
189
+ 'list-langs': { type: 'boolean' },
190
+ 'list-charsets': { type: 'boolean' },
191
+ 'help': { type: 'boolean', short: 'h' },
192
+ 'version': { type: 'boolean', short: 'V' },
193
+ });
194
+
195
+ if (values.help) {
196
+ process.stdout.write(WBXML2XML_HELP);
197
+ return;
198
+ }
199
+ if (values.version) {
200
+ process.stdout.write(`wbxml2xml (@sie-js/wbxml) ${getPackageVersion()}\n`);
201
+ return;
202
+ }
203
+ if (values['list-langs'] || values['list-charsets']) {
204
+ if (values['list-langs'])
205
+ process.stdout.write(`Languages:\n${formatList(LANG_DESCRIPTIONS)}\n`);
206
+ if (values['list-charsets'])
207
+ process.stdout.write(`Charsets:\n${formatList(CHARSET_DESCRIPTIONS)}\n`);
208
+ return;
209
+ }
210
+
211
+ const input = await readInput(getSingleInput(positionals));
212
+ let xml: string;
213
+ try {
214
+ xml = wbxml2xml(input, {
215
+ mode: parseMode(values.mode) as WBXMLGenMode | undefined,
216
+ indent: values.indent === undefined ? undefined : Number(values.indent),
217
+ preserveWhitespace: values['keep-whitespace'],
218
+ lang: values.lang as WBXMLLang | undefined,
219
+ charset: values.charset as WBXMLCharset | undefined,
220
+ });
221
+ } catch (e) {
222
+ if (values.lang === undefined && (e as Error).message === 'Unknown Public ID')
223
+ throw new Error('Unknown Public ID (the document has no known public ID, use -l <lang> to force the language; see --list-langs)');
224
+ throw e;
225
+ }
226
+ await writeOutput(values.output, xml);
227
+ }
228
+
229
+ async function runXml2wbxml(argv: string[]): Promise<void> {
230
+ const { values, positionals } = parse(argv, {
231
+ 'output': { type: 'string', short: 'o' },
232
+ 'wbxml-version': { type: 'string', short: 'v' },
233
+ 'keep-whitespace': { type: 'boolean', short: 'k' },
234
+ 'no-string-table': { type: 'boolean', short: 'n' },
235
+ 'anonymous': { type: 'boolean', short: 'a' },
236
+ 'help': { type: 'boolean', short: 'h' },
237
+ 'version': { type: 'boolean', short: 'V' },
238
+ });
239
+
240
+ if (values.help) {
241
+ process.stdout.write(XML2WBXML_HELP);
242
+ return;
243
+ }
244
+ if (values.version) {
245
+ process.stdout.write(`xml2wbxml (@sie-js/wbxml) ${getPackageVersion()}\n`);
246
+ return;
247
+ }
248
+
249
+ if (values.output === undefined && process.stdout.isTTY)
250
+ throw new UsageError(`refusing to write binary WBXML to a terminal (use -o <file>, or '-o -' to force)`);
251
+
252
+ const input = await readInput(getSingleInput(positionals));
253
+ const wbxml = xml2wbxml(input, {
254
+ version: values['wbxml-version'] as WBXMLVersion | undefined,
255
+ preserveWhitespace: values['keep-whitespace'],
256
+ noStringTable: values['no-string-table'],
257
+ noPublicId: values.anonymous,
258
+ });
259
+ await writeOutput(values.output, wbxml);
260
+ }
261
+
262
+ async function runWbxml(argv: string[]): Promise<void> {
263
+ const [command, ...rest] = argv;
264
+ switch (command) {
265
+ case 'decode':
266
+ case 'wbxml2xml':
267
+ await runWbxml2xml(rest);
268
+ break;
269
+ case 'encode':
270
+ case 'xml2wbxml':
271
+ await runXml2wbxml(rest);
272
+ break;
273
+ case 'langs':
274
+ process.stdout.write(`${formatList(LANG_DESCRIPTIONS)}\n`);
275
+ break;
276
+ case 'charsets':
277
+ process.stdout.write(`${formatList(CHARSET_DESCRIPTIONS)}\n`);
278
+ break;
279
+ case '-h':
280
+ case '--help':
281
+ process.stdout.write(WBXML_HELP);
282
+ break;
283
+ case '-V':
284
+ case '--version':
285
+ process.stdout.write(`wbxml (@sie-js/wbxml) ${getPackageVersion()}\n`);
286
+ break;
287
+ case undefined:
288
+ process.stderr.write(WBXML_HELP);
289
+ process.exitCode = 2;
290
+ break;
291
+ default:
292
+ throw new UsageError(`unknown command '${command}' (see 'wbxml --help')`);
293
+ }
294
+ }
295
+
296
+ const TOOLS = {
297
+ wbxml: runWbxml,
298
+ wbxml2xml: runWbxml2xml,
299
+ xml2wbxml: runXml2wbxml,
300
+ };
301
+
302
+ export async function main(tool: keyof typeof TOOLS): Promise<void> {
303
+ // Output closed early (e.g. piped to head): exit quietly.
304
+ process.stdout.on('error', (err: NodeJS.ErrnoException) => {
305
+ if (err.code !== 'EPIPE')
306
+ throw err;
307
+ process.exit(process.exitCode ?? 0);
308
+ });
309
+
310
+ try {
311
+ await TOOLS[tool](process.argv.slice(2));
312
+ } catch (e) {
313
+ const err = e as Error;
314
+ if (err instanceof UsageError || err instanceof WBXMLOptionError) {
315
+ process.stderr.write(`${tool}: ${err.message}\nTry '${tool} --help' for more information.\n`);
316
+ process.exitCode = 2;
317
+ } else {
318
+ process.stderr.write(`${tool}: ${err.message}\n`);
319
+ process.exitCode = 1;
320
+ }
321
+ }
322
+ }
package/src/index.ts ADDED
@@ -0,0 +1,191 @@
1
+ import Module from '#build/wbxml.js';
2
+
3
+ export const WBXML_VERSIONS = ['1.0', '1.1', '1.2', '1.3'] as const;
4
+
5
+ export const WBXML_LANGS = [
6
+ 'WML10',
7
+ 'WML11',
8
+ 'WML12',
9
+ 'WML13',
10
+ 'WTA10',
11
+ 'WTAWML12',
12
+ 'CHANNEL11',
13
+ 'CHANNEL12',
14
+ 'SI10',
15
+ 'SL10',
16
+ 'CO10',
17
+ 'PROV10',
18
+ 'EMN10',
19
+ 'DRMREL10',
20
+ 'OTA',
21
+ 'SYNCML10',
22
+ 'DEVINF10',
23
+ 'SYNCML11',
24
+ 'DEVINF11',
25
+ 'METINF11',
26
+ 'SYNCML12',
27
+ 'DEVINF12',
28
+ 'METINF12',
29
+ 'DMDDF12',
30
+ 'CSP11',
31
+ 'CSP12',
32
+ 'AIRSYNC',
33
+ 'ACTIVESYNC',
34
+ 'CONML',
35
+ ] as const;
36
+
37
+ export const WBXML_CHARSETS = [
38
+ 'ASCII',
39
+ 'ISO-8859-1',
40
+ 'ISO-8859-2',
41
+ 'ISO-8859-3',
42
+ 'ISO-8859-4',
43
+ 'ISO-8859-5',
44
+ 'ISO-8859-6',
45
+ 'ISO-8859-7',
46
+ 'ISO-8859-8',
47
+ 'ISO-8859-9',
48
+ 'ISO-10646-UCS-2',
49
+ 'SHIFT_JIS',
50
+ 'BIG5',
51
+ 'UTF-8',
52
+ 'UTF-16',
53
+ ] as const;
54
+
55
+ export const WBXML_GEN_MODES = ['compact', 'indent', 'canonical'] as const;
56
+
57
+ export type WBXMLVersion = typeof WBXML_VERSIONS[number];
58
+ export type WBXMLLang = typeof WBXML_LANGS[number];
59
+ export type WBXMLCharset = typeof WBXML_CHARSETS[number];
60
+ export type WBXMLGenMode = typeof WBXML_GEN_MODES[number];
61
+
62
+ export interface OptionsToWBXML {
63
+ /** WBXML version of the output document (default: 1.3). */
64
+ version?: WBXMLVersion | undefined;
65
+ /** Keep ignorable whitespaces. */
66
+ preserveWhitespace?: boolean | undefined;
67
+ /** Do not generate the string table. */
68
+ noStringTable?: boolean | undefined;
69
+ /** Anonymous document: do not include public ID or DTD. */
70
+ noPublicId?: boolean | undefined;
71
+ }
72
+
73
+ export interface OptionsFromWBXML {
74
+ /** XML generation mode (default: indent). */
75
+ mode?: WBXMLGenMode | undefined;
76
+ /** Indent delta for the 'indent' mode (default: 0). */
77
+ indent?: number | undefined;
78
+ /** Keep ignorable whitespaces. */
79
+ preserveWhitespace?: boolean | undefined;
80
+ /** Force the language of the document. */
81
+ lang?: WBXMLLang | undefined;
82
+ /** Charset used when the document does not specify one. */
83
+ charset?: WBXMLCharset | undefined;
84
+ }
85
+
86
+ /** Thrown when a conversion option has an unsupported value. */
87
+ export class WBXMLOptionError extends RangeError {}
88
+
89
+ const WBXML = await Module();
90
+
91
+ const _xml2wbxml = WBXML.cwrap('xml2wbxml', 'number', [
92
+ 'number', // xml_in
93
+ 'number', // xml_in_len
94
+ 'number', // out**
95
+ 'number', // out_len*
96
+ 'string', // wbxml_version
97
+ 'number', // preserve_whitespace
98
+ 'number', // no_string_table
99
+ 'number', // no_public_id
100
+ ]);
101
+
102
+ const _wbxml2xml = WBXML.cwrap('wbxml2xml', 'number', [
103
+ 'number', // wbxml_in
104
+ 'number', // wbxml_in_len
105
+ 'number', // out**
106
+ 'number', // out_len*
107
+ 'number', // gen_type
108
+ 'number', // indent
109
+ 'number', // preserve_whitespace
110
+ 'string', // force_lang
111
+ 'string', // force_charset
112
+ ]);
113
+
114
+ function checkOption<T extends string>(name: string, value: T | undefined, allowed: readonly T[]): void {
115
+ if (value !== undefined && !allowed.includes(value))
116
+ throw new WBXMLOptionError(`Unknown ${name} '${value}' (expected one of: ${allowed.join(', ')})`);
117
+ }
118
+
119
+ /**
120
+ * Copies the input into the wasm heap, runs the converter and returns its output.
121
+ * The converter must store a malloc'ed result (or error message) in *out / *out_len.
122
+ */
123
+ function convert(input: Uint8Array, run: (inPtr: number, inLen: number, outPtrPtr: number, outLenPtr: number) => number): Buffer {
124
+ const inPtr = WBXML._malloc(input.length || 1);
125
+ const outPtrPtr = WBXML._malloc(4);
126
+ const outLenPtr = WBXML._malloc(4);
127
+ try {
128
+ WBXML.HEAPU8.set(input, inPtr);
129
+ WBXML.HEAPU32[outPtrPtr >> 2] = 0;
130
+ WBXML.HEAPU32[outLenPtr >> 2] = 0;
131
+
132
+ const rc = run(inPtr, input.length, outPtrPtr, outLenPtr);
133
+
134
+ const outPtr = WBXML.HEAPU32[outPtrPtr >> 2]!;
135
+ const outLen = WBXML.HEAPU32[outLenPtr >> 2]!;
136
+ const result = Buffer.from(WBXML.HEAPU8.slice(outPtr, outPtr + outLen));
137
+ WBXML._free(outPtr);
138
+
139
+ if (rc !== 0)
140
+ throw new Error(result.toString());
141
+ return result;
142
+ } finally {
143
+ WBXML._free(inPtr);
144
+ WBXML._free(outPtrPtr);
145
+ WBXML._free(outLenPtr);
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Converts an XML document to WBXML.
151
+ * A string is encoded as UTF-8; pass raw bytes to use the encoding from the XML declaration.
152
+ */
153
+ export function xml2wbxml(xml: string | Uint8Array, opts: OptionsToWBXML = {}): Buffer {
154
+ const { version = '1.3' } = opts;
155
+ checkOption('WBXML version', version, WBXML_VERSIONS);
156
+ const input = typeof xml === 'string' ? Buffer.from(xml) : xml;
157
+ return convert(input, (inPtr, inLen, outPtrPtr, outLenPtr) => _xml2wbxml(
158
+ inPtr,
159
+ inLen,
160
+ outPtrPtr,
161
+ outLenPtr,
162
+ version,
163
+ opts.preserveWhitespace ? 1 : 0,
164
+ opts.noStringTable ? 1 : 0,
165
+ opts.noPublicId ? 1 : 0
166
+ ));
167
+ }
168
+
169
+ /**
170
+ * Converts a WBXML document to an XML string.
171
+ */
172
+ export function wbxml2xml(wbxml: Uint8Array, opts: OptionsFromWBXML = {}): string {
173
+ const { mode = 'indent', indent, lang, charset } = opts;
174
+ checkOption('mode', mode, WBXML_GEN_MODES);
175
+ checkOption('language', lang, WBXML_LANGS);
176
+ checkOption('charset', charset, WBXML_CHARSETS);
177
+ if (indent !== undefined && !(Number.isInteger(indent) && indent >= 0 && indent <= 127))
178
+ throw new WBXMLOptionError(`Invalid indent '${indent}' (expected 0..127)`);
179
+
180
+ return convert(wbxml, (inPtr, inLen, outPtrPtr, outLenPtr) => _wbxml2xml(
181
+ inPtr,
182
+ inLen,
183
+ outPtrPtr,
184
+ outLenPtr,
185
+ WBXML_GEN_MODES.indexOf(mode),
186
+ indent ?? -1,
187
+ opts.preserveWhitespace ? 1 : 0,
188
+ lang ?? '',
189
+ charset ?? ''
190
+ )).toString();
191
+ }
@@ -1,19 +0,0 @@
1
- export type WBXMLVersion = "1.0" | "1.1" | "1.2" | "1.3";
2
- export type WBXMLLang = "WML10" | "WML11" | "WML12" | "WML13" | "WTA10" | "WTAWML12" | "CHANNEL11" | "CHANNEL12" | "SI10" | "SL10" | "CO10" | "PROV10" | "EMN10" | "DRMREL10" | "OTA" | "SYNCML10" | "DEVINF10" | "SYNCML11" | "DEVINF11" | "METINF11" | "SYNCML12" | "DEVINF12" | "METINF12" | "DMDDF12" | "CSP11" | "CSP12" | "AIRSYNC" | "ACTIVESYNC" | "CONML";
3
- export type WBXMLCharset = "ASCII" | "ISO-8859-1" | "ISO-8859-2" | "ISO-8859-3" | "ISO-8859-4" | "ISO-8859-5" | "ISO-8859-6" | "ISO-8859-7" | "ISO-8859-8" | "ISO-8859-9" | "ISO-10646-UCS-2" | "SHIFT_JIS" | "BIG5" | "UTF-8" | "UTF-16";
4
- interface OptionsToWBXML {
5
- version?: WBXMLVersion;
6
- preserveWhitespace?: boolean;
7
- noStringTable?: boolean;
8
- noPublicId?: boolean;
9
- }
10
- interface OptionsFromWBXML {
11
- mode?: "compact" | "indent" | "canonical";
12
- indent?: number;
13
- preserveWhitespace?: boolean;
14
- lang?: WBXMLLang;
15
- charset?: WBXMLCharset;
16
- }
17
- export declare function xml2wbxml(xml: string, opts?: OptionsToWBXML): Buffer;
18
- export declare function wbxml2xml(wbxml: Buffer, opts?: OptionsFromWBXML): string;
19
- export {};
package/dist/src/index.js DELETED
@@ -1,69 +0,0 @@
1
- import Module from "#build/wbxml.js";
2
- const WBXML = await Module();
3
- const _xml2wbxml = WBXML.cwrap('xml2wbxml', 'number', [
4
- 'number', // xml_in
5
- 'number', // xml_in_len
6
- 'number', // out**
7
- 'number', // out_len*
8
- 'string', // wbxml_version
9
- 'number', // preserve_whitespace
10
- 'number', // no_string_table
11
- 'number', // no_public_id
12
- ]);
13
- const _wbxml2xml = WBXML.cwrap("wbxml2xml", "number", [
14
- "number", // wbxml_in
15
- "number", // wbxml_in_len
16
- "number", // out
17
- "number", // out_len
18
- "number", // gen_type
19
- "number", // indent
20
- "number", // preserve_whitespace
21
- "string", // force_lang
22
- "string", // force_charset
23
- ]);
24
- export function xml2wbxml(xml, opts = {}) {
25
- const { version = "1.3", preserveWhitespace = false, noStringTable = false, noPublicId = false, } = opts;
26
- const xmlBytes = Buffer.from(xml);
27
- const xmlPtr = WBXML._malloc(xmlBytes.length || 1);
28
- WBXML.HEAPU8.set(xmlBytes, xmlPtr);
29
- const outPtrPtr = WBXML._malloc(4);
30
- const outLenPtr = WBXML._malloc(4);
31
- WBXML.HEAPU32[outPtrPtr >> 2] = 0;
32
- WBXML.HEAPU32[outLenPtr >> 2] = 0;
33
- const rc = _xml2wbxml(xmlPtr, xmlBytes.length, outPtrPtr, outLenPtr, version, preserveWhitespace ? 1 : 0, noStringTable ? 1 : 0, noPublicId ? 1 : 0);
34
- const outPtr = WBXML.HEAPU32[outPtrPtr >> 2] >>> 0;
35
- const outLen = WBXML.HEAPU32[outLenPtr >> 2] >>> 0;
36
- const result = Buffer.from(WBXML.HEAPU8.slice(outPtr, outPtr + outLen));
37
- WBXML._free(xmlPtr);
38
- WBXML._free(outPtrPtr);
39
- WBXML._free(outLenPtr);
40
- WBXML._free(outPtr);
41
- if (rc !== 0)
42
- throw new Error(result.toString());
43
- return result;
44
- }
45
- export function wbxml2xml(wbxml, opts = {}) {
46
- const { mode = "indent", indent = -1, preserveWhitespace = false, lang = undefined, charset = undefined, } = opts;
47
- const inPtr = WBXML._malloc(wbxml.length);
48
- WBXML.HEAPU8.set(wbxml, inPtr);
49
- const outPtrPtr = WBXML._malloc(4);
50
- const outLenPtr = WBXML._malloc(4);
51
- const modeToNumber = {
52
- compact: 0,
53
- indent: 1,
54
- canonical: 2,
55
- };
56
- if (!(mode in modeToNumber))
57
- throw new Error(`Unknown mode: ${mode}`);
58
- const rc = _wbxml2xml(inPtr, wbxml.length, outPtrPtr, outLenPtr, modeToNumber[mode], indent, preserveWhitespace ? 1 : 0, lang, charset);
59
- const outPtr = WBXML.HEAPU32[outPtrPtr >> 2] >>> 0;
60
- const outLen = WBXML.HEAPU32[outLenPtr >> 2] >>> 0;
61
- const result = Buffer.from(WBXML.HEAPU8.slice(outPtr, outPtr + outLen));
62
- WBXML._free(inPtr);
63
- WBXML._free(outPtrPtr);
64
- WBXML._free(outLenPtr);
65
- WBXML._free(outPtr);
66
- if (rc !== 0)
67
- throw new Error(result.toString());
68
- return result.toString();
69
- }