whatwg-encoding.js
 1  "use strict";
 2  const iconvLite = require("iconv-lite");
 3  const supportedNames = require("./supported-names.json");
 4  const labelsToNames = require("./labels-to-names.json");
 5  
 6  const supportedNamesSet = new Set(supportedNames);
 7  
 8  // https://encoding.spec.whatwg.org/#concept-encoding-get
 9  exports.labelToName = label => {
10    label = String(label).trim().toLowerCase();
11  
12    return labelsToNames[label] || null;
13  };
14  
15  // https://encoding.spec.whatwg.org/#decode
16  exports.decode = (buffer, fallbackEncodingName) => {
17    let encoding = fallbackEncodingName;
18    if (!exports.isSupported(encoding)) {
19      throw new RangeError(`"${encoding}" is not a supported encoding name`);
20    }
21  
22    const bomEncoding = exports.getBOMEncoding(buffer);
23    if (bomEncoding !== null) {
24      encoding = bomEncoding;
25    }
26  
27    // iconv-lite will strip BOMs for us, so no need to do the stuff the spec does
28  
29    return iconvLite.decode(buffer, encoding);
30  };
31  
32  // https://github.com/whatwg/html/issues/1910#issuecomment-254017369
33  exports.getBOMEncoding = buffer => {
34    if (buffer[0] === 0xFE && buffer[1] === 0xFF) {
35      return "UTF-16BE";
36    } else if (buffer[0] === 0xFF && buffer[1] === 0xFE) {
37      return "UTF-16LE";
38    } else if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
39      return "UTF-8";
40    }
41  
42    return null;
43  };
44  
45  exports.isSupported = name => {
46    return supportedNamesSet.has(String(name));
47  };