index.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. "use strict"
  2. var Buffer = require("safer-buffer").Buffer
  3. var bomHandling = require("./bom-handling")
  4. var mergeModules = require("./helpers/merge-exports")
  5. var iconv = module.exports
  6. // All codecs and aliases are kept here, keyed by encoding name/alias.
  7. // They are lazy loaded in `iconv.getCodec` from `encodings/index.js`.
  8. // Cannot initialize with { __proto__: null } because Boolean({ __proto__: null }) === true
  9. iconv.encodings = null
  10. // Characters emitted in case of error.
  11. iconv.defaultCharUnicode = "�"
  12. iconv.defaultCharSingleByte = "?"
  13. // Public API.
  14. iconv.encode = function encode (str, encoding, options) {
  15. str = "" + (str || "") // Ensure string.
  16. var encoder = iconv.getEncoder(encoding, options)
  17. var res = encoder.write(str)
  18. var trail = encoder.end()
  19. return (trail && trail.length > 0) ? Buffer.concat([res, trail]) : res
  20. }
  21. iconv.decode = function decode (buf, encoding, options) {
  22. if (typeof buf === "string") {
  23. if (!iconv.skipDecodeWarning) {
  24. console.error("Iconv-lite warning: decode()-ing strings is deprecated. Refer to https://github.com/ashtuchkin/iconv-lite/wiki/Use-Buffers-when-decoding")
  25. iconv.skipDecodeWarning = true
  26. }
  27. buf = Buffer.from("" + (buf || ""), "binary") // Ensure buffer.
  28. }
  29. var decoder = iconv.getDecoder(encoding, options)
  30. var res = decoder.write(buf)
  31. var trail = decoder.end()
  32. return trail ? (res + trail) : res
  33. }
  34. iconv.encodingExists = function encodingExists (enc) {
  35. try {
  36. iconv.getCodec(enc)
  37. return true
  38. } catch (e) {
  39. return false
  40. }
  41. }
  42. // Legacy aliases to convert functions
  43. iconv.toEncoding = iconv.encode
  44. iconv.fromEncoding = iconv.decode
  45. // Search for a codec in iconv.encodings. Cache codec data in iconv._codecDataCache.
  46. iconv._codecDataCache = { __proto__: null }
  47. iconv.getCodec = function getCodec (encoding) {
  48. if (!iconv.encodings) {
  49. var raw = require("../encodings")
  50. // TODO: In future versions when old nodejs support is removed can use object.assign
  51. iconv.encodings = { __proto__: null } // Initialize as empty object.
  52. mergeModules(iconv.encodings, raw)
  53. }
  54. // Canonicalize encoding name: strip all non-alphanumeric chars and appended year.
  55. var enc = iconv._canonicalizeEncoding(encoding)
  56. // Traverse iconv.encodings to find actual codec.
  57. var codecOptions = {}
  58. while (true) {
  59. var codec = iconv._codecDataCache[enc]
  60. if (codec) { return codec }
  61. var codecDef = iconv.encodings[enc]
  62. switch (typeof codecDef) {
  63. case "string": // Direct alias to other encoding.
  64. enc = codecDef
  65. break
  66. case "object": // Alias with options. Can be layered.
  67. for (var key in codecDef) { codecOptions[key] = codecDef[key] }
  68. if (!codecOptions.encodingName) { codecOptions.encodingName = enc }
  69. enc = codecDef.type
  70. break
  71. case "function": // Codec itself.
  72. if (!codecOptions.encodingName) { codecOptions.encodingName = enc }
  73. // The codec function must load all tables and return object with .encoder and .decoder methods.
  74. // It'll be called only once (for each different options object).
  75. //
  76. codec = new codecDef(codecOptions, iconv)
  77. iconv._codecDataCache[codecOptions.encodingName] = codec // Save it to be reused later.
  78. return codec
  79. default:
  80. throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '" + enc + "')")
  81. }
  82. }
  83. }
  84. iconv._canonicalizeEncoding = function (encoding) {
  85. // Canonicalize encoding name: strip all non-alphanumeric chars and appended year.
  86. return ("" + encoding).toLowerCase().replace(/:\d{4}$|[^0-9a-z]/g, "")
  87. }
  88. iconv.getEncoder = function getEncoder (encoding, options) {
  89. var codec = iconv.getCodec(encoding)
  90. var encoder = new codec.encoder(options, codec)
  91. if (codec.bomAware && options && options.addBOM) { encoder = new bomHandling.PrependBOM(encoder, options) }
  92. return encoder
  93. }
  94. iconv.getDecoder = function getDecoder (encoding, options) {
  95. var codec = iconv.getCodec(encoding)
  96. var decoder = new codec.decoder(options, codec)
  97. if (codec.bomAware && !(options && options.stripBOM === false)) { decoder = new bomHandling.StripBOM(decoder, options) }
  98. return decoder
  99. }
  100. // Streaming API
  101. // NOTE: Streaming API naturally depends on 'stream' module from Node.js. Unfortunately in browser environments this module can add
  102. // up to 100Kb to the output bundle. To avoid unnecessary code bloat, we don't enable Streaming API in browser by default.
  103. // If you would like to enable it explicitly, please add the following code to your app:
  104. // > iconv.enableStreamingAPI(require('stream'));
  105. iconv.enableStreamingAPI = function enableStreamingAPI (streamModule) {
  106. if (iconv.supportsStreams) { return }
  107. // Dependency-inject stream module to create IconvLite stream classes.
  108. var streams = require("./streams")(streamModule)
  109. // Not public API yet, but expose the stream classes.
  110. iconv.IconvLiteEncoderStream = streams.IconvLiteEncoderStream
  111. iconv.IconvLiteDecoderStream = streams.IconvLiteDecoderStream
  112. // Streaming API.
  113. iconv.encodeStream = function encodeStream (encoding, options) {
  114. return new iconv.IconvLiteEncoderStream(iconv.getEncoder(encoding, options), options)
  115. }
  116. iconv.decodeStream = function decodeStream (encoding, options) {
  117. return new iconv.IconvLiteDecoderStream(iconv.getDecoder(encoding, options), options)
  118. }
  119. iconv.supportsStreams = true
  120. }
  121. // Enable Streaming API automatically if 'stream' module is available and non-empty (the majority of environments).
  122. var streamModule
  123. try {
  124. streamModule = require("stream")
  125. } catch (e) {}
  126. if (streamModule && streamModule.Transform) {
  127. iconv.enableStreamingAPI(streamModule)
  128. } else {
  129. // In rare cases where 'stream' module is not available by default, throw a helpful exception.
  130. iconv.encodeStream = iconv.decodeStream = function () {
  131. throw new Error("iconv-lite Streaming API is not enabled. Use iconv.enableStreamingAPI(require('stream')); to enable it.")
  132. }
  133. }
  134. // Some environments, such as browsers, may not load JavaScript files as UTF-8
  135. // eslint-disable-next-line no-constant-condition
  136. if ("Ā" !== "\u0100") {
  137. console.error("iconv-lite warning: js files use non-utf8 encoding. See https://github.com/ashtuchkin/iconv-lite/wiki/Javascript-source-file-encodings for more info.")
  138. }