UNPKG

6.82 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.assertNoXmlElementChildNodes = assertNoXmlElementChildNodes;
7exports.assertXmlTagName = assertXmlTagName;
8exports.base64Decode = base64Decode;
9exports.base64Encode = base64Encode;
10exports.xmlDecode = xmlDecode;
11exports.xmlElementChildElements = xmlElementChildElements;
12exports.xmlElementText = xmlElementText;
13var _xmldom = require("@xmldom/xmldom");
14const B6 = 0x3f;
15const B8 = 0xff;
16const C64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
17const C64M = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 64, -1, -1, -1, 0, 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, -1, -1, -1, -1, -1, -1, 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];
18/**
19 * Decode an XML string.
20 *
21 * @param xml XML string.
22 * @returns Decoded declaration, doctype, and document element.
23 */
24function xmlDecode(xml) {
25 let declaration = null;
26 let doctype = null;
27 const errors = [];
28 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
29 const parser = new _xmldom.DOMParser({
30 locator: {},
31 errorHandler: {
32 /**
33 * Warning callback.
34 *
35 * @param e Error string.
36 */
37 warning: e => {
38 // Ignore warnings.
39 },
40 /**
41 * Error callback.
42 *
43 * @param e Error string.
44 */
45 error: e => {
46 errors.push(e);
47 },
48 /**
49 * Fatal error callback.
50 *
51 * @param e Error string.
52 */
53 fatalError: e => {
54 errors.push(e);
55 }
56 }
57 });
58 const doc = parser.parseFromString(xml, 'text/xml');
59 if (errors.length) {
60 throw new Error(`XML decode error: ${errors[0]}`);
61 }
62 const {
63 childNodes
64 } = doc;
65 const documentElement = doc.documentElement || null;
66 for (let i = 0, l = childNodes.length; i < l; i++) {
67 const childNode = childNodes[i];
68 if (childNode === documentElement) {
69 break;
70 }
71 const str = childNode.toString();
72 if (/^<\?xml[^>]*\?>$/.test(str)) {
73 declaration = str;
74 }
75 if (/^<!DOCTYPE[^>]*>$/.test(str)) {
76 doctype = str;
77 }
78 }
79 if (!documentElement) {
80 throw new Error('XML decode error: No document element');
81 }
82 return {
83 declaration,
84 doctype,
85 documentElement
86 };
87}
88
89/**
90 * List XML element child elements.
91 * Throws if non-whitespace nodes are found.
92 *
93 * @param element XML element.
94 * @returns XML element list.
95 */
96function xmlElementChildElements(element) {
97 const {
98 childNodes
99 } = element;
100 const r = [];
101 for (let i = 0, l = childNodes.length; i < l; i++) {
102 const childNode = childNodes[i];
103 if ('tagName' in childNode) {
104 r.push(childNode);
105 continue;
106 }
107 const {
108 nodeValue
109 } = childNode;
110 if (nodeValue && !/^\s*$/.test(nodeValue)) {
111 throw new Error(`Found text children of: ${element.tagName}`);
112 }
113 }
114 return r;
115}
116
117/**
118 * Get the XML element text node.
119 * Returns null if none, throws if multiple elements.
120 *
121 * @param element XML element.
122 * @returns XML text node list.
123 */
124function xmlElementText(element) {
125 const {
126 childNodes
127 } = element;
128 let r = null;
129 for (let i = 0, l = childNodes.length; i < l; i++) {
130 if (i) {
131 throw new Error(`Multiple child elements in: ${element.tagName}`);
132 }
133 const childNode = childNodes[i];
134 if (!('tagName' in childNode) && 'data' in childNode && 'nodeValue' in childNode) {
135 r = childNode;
136 } else {
137 throw new Error(`Unexpected child element in: ${element.tagName}`);
138 }
139 }
140 return r;
141}
142
143/**
144 * Assert XML element has no children.
145 *
146 * @param element XML element.
147 * @param tagName XML element tag name.
148 */
149function assertXmlTagName(element, tagName) {
150 const tn = element.tagName;
151 if (tn !== tagName) {
152 throw new Error(`Unexpected tagName: ${tagName}`);
153 }
154}
155
156/**
157 * Assert XML element has no children.
158 *
159 * @param element XML element.
160 */
161function assertNoXmlElementChildNodes(element) {
162 const {
163 childNodes
164 } = element;
165 if (childNodes.length) {
166 throw new Error(`Unexpected child nodes: ${element.tagName}`);
167 }
168}
169
170/**
171 * Base64 encode function mirroring decode function.
172 *
173 * @param data Byte array.
174 * @returns Base64 string.
175 */
176function base64Encode(data) {
177 const l = data.length;
178 let r = '';
179 for (let i = 0; i < l;) {
180 const a = data[i++];
181 const b = i < l ? data[i++] : null;
182 const c = i < l ? data[i++] : null;
183 // eslint-disable-next-line no-bitwise
184 const o = a << 16 | (b || 0) << 8 | (c || 0);
185 r +=
186 // eslint-disable-next-line no-bitwise
187 C64[o >> 18] +
188 // eslint-disable-next-line no-bitwise
189 C64[o >> 12 & B6] +
190 // eslint-disable-next-line no-bitwise
191 C64[b === null ? 64 : o >> 6 & B6] +
192 // eslint-disable-next-line no-bitwise
193 C64[c === null ? 64 : o & B6];
194 }
195 return r;
196}
197
198/**
199 * Base64 decode function that matches plist parsing behavior.
200 *
201 * @param base64 Base64 string.
202 * @returns Byte array.
203 */
204function base64Decode(base64) {
205 const l = base64.length;
206 const r = [];
207 OUTER: for (let a, b, c, d, m, z, i = 0; i < l;) {
208 for (;;) {
209 if ((m = C64M[base64.charCodeAt(i++)]) >= 0) {
210 a = m;
211 break;
212 }
213 if (i >= l) {
214 break OUTER;
215 }
216 }
217 for (;;) {
218 if ((m = C64M[base64.charCodeAt(i++)]) >= 0) {
219 b = m;
220 break;
221 }
222 if (i >= l) {
223 break OUTER;
224 }
225 }
226 for (;;) {
227 if ((m = C64M[base64.charCodeAt(i++)]) >= 0) {
228 c = m;
229 break;
230 }
231 if (i >= l) {
232 break OUTER;
233 }
234 }
235 for (;;) {
236 if ((m = C64M[base64.charCodeAt(i++)]) >= 0) {
237 d = m;
238 break;
239 }
240 if (i >= l) {
241 break OUTER;
242 }
243 }
244 // eslint-disable-next-line no-bitwise
245 z = (a & B6) << 18 | (b & B6) << 12 | (c & B6) << 6 | d & B6;
246 // eslint-disable-next-line default-case, no-nested-ternary
247 switch (c > B6 ? d > B6 ? 2 : 0 : d > B6 ? 1 : 0) {
248 case 0:
249 {
250 // eslint-disable-next-line no-bitwise
251 r.push(z >> 16 & B8, z >> 8 & B8, z & B8);
252 break;
253 }
254 case 1:
255 {
256 // eslint-disable-next-line no-bitwise
257 r.push(z >> 16 & B8, z >> 8 & B8);
258 break;
259 }
260 case 2:
261 {
262 // eslint-disable-next-line no-bitwise
263 r.push(z >> 16 & B8);
264 break;
265 }
266 }
267 }
268 return new Uint8Array(r);
269}
270//# sourceMappingURL=util.js.map
\No newline at end of file