TextEncoder.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. var defaultEncoding_1 = require("../encoding/defaultEncoding");
  4. var encoding_factory_1 = require("../encoding/encoding-factory");
  5. var encodings_1 = require("../encoding/encodings");
  6. var finished_1 = require("../encoding/finished");
  7. var terminology_1 = require("../encoding/terminology");
  8. var utilities_1 = require("../encoding/utilities");
  9. var getGlobalScope_1 = require("../helper/getGlobalScope");
  10. var Stream_1 = require("./Stream");
  11. /**
  12. * @constructor
  13. * @param {string=} label The label of the encoding. NONSTANDARD.
  14. * @param {Object=} options NONSTANDARD.
  15. */
  16. var TextEncoder = /** @class */ (function () {
  17. function TextEncoder(label, options) {
  18. var optionsMap = utilities_1.ToDictionary(options);
  19. // A TextEncoder object has an associated encoding and encoder.
  20. /** @private */
  21. this._encoding = null;
  22. /** @private @type {?Encoder} */
  23. this._encoder = null;
  24. // Non-standard
  25. /** @private @type {boolean} */
  26. this._do_not_flush = false;
  27. /** @private @type {string} */
  28. this._fatal = Boolean(optionsMap['fatal']) ? 'fatal' : 'replacement';
  29. // 1. Let enc be a new TextEncoder object.
  30. // const enc = this;
  31. // no need to do this as this is a proper class
  32. // now and TSC will handle transpilation to older platforms
  33. // 2. Set enc's encoding to UTF-8's encoder.
  34. if (Boolean(optionsMap['NONSTANDARD_allowLegacyEncoding'])) {
  35. // NONSTANDARD behavior.
  36. label = !!label ? String(label) : defaultEncoding_1.DEFAULT_ENCODING;
  37. var encoding = encodings_1.getEncoding(label);
  38. if (encoding === null || encoding.name === 'replacement')
  39. throw RangeError('Unknown encoding: ' + label);
  40. if (!encoding_factory_1.encoders[encoding.name]) {
  41. throw Error('Encoder not present.' +
  42. ' Did you forget to include encoding-indexes.js first?');
  43. }
  44. this._encoding = encoding;
  45. // EXPERIMENTAL_CODE
  46. // } else if (["iso-8859-1", "ISO-8859-1", "latin-1", "latin1", "LATIN-1", "LATIN1"].indexOf(label) !== -1) {
  47. // this._encoding = getEncoding('iso-8859-1');
  48. }
  49. else {
  50. // Standard behavior.
  51. this._encoding = encodings_1.getEncoding('utf-8');
  52. var glo = getGlobalScope_1.getGlobalScope() || {};
  53. if (label !== undefined && 'console' in glo) {
  54. console.warn('TextEncoder constructor called with encoding label, '
  55. + 'which is ignored.');
  56. }
  57. }
  58. // For pre-ES5 runtimes:
  59. // if (!Object.defineProperty)
  60. // this.encoding = enc._encoding.name.toLowerCase();
  61. // 3. Return enc.
  62. // return enc;
  63. }
  64. Object.defineProperty(TextEncoder.prototype, "encoding", {
  65. // if(Object.defineProperty) {
  66. // // The encoding attribute's getter must return encoding's name.
  67. // Object.defineProperty(TextEncoder.prototype, 'encoding', {
  68. // /** @this {TextEncoder} */
  69. // get: function () { return this._encoding.name.toLowerCase(); }
  70. // });
  71. // }
  72. get: function () {
  73. return this._encoding.name.toLowerCase();
  74. },
  75. enumerable: true,
  76. configurable: true
  77. });
  78. /**
  79. * @param {string=} opt_string The string to encode.
  80. * @param {Object=} options
  81. * @return {!Uint8Array} Encoded bytes, as a Uint8Array.
  82. */
  83. TextEncoder.prototype.encode = function (opt_string, options) {
  84. opt_string = opt_string === undefined ? '' : String(opt_string);
  85. var optionsMap = utilities_1.ToDictionary(options);
  86. // NOTE: This option is nonstandard. None of the encodings
  87. // permitted for encoding (i.e. UTF-8, UTF-16) are stateful when
  88. // the input is a USVString so streaming is not necessary.
  89. if (!this._do_not_flush)
  90. this._encoder = encoding_factory_1.encoders[this._encoding.name]({
  91. fatal: this._fatal === 'fatal'
  92. });
  93. this._do_not_flush = Boolean(optionsMap['stream']);
  94. // 1. Convert input to a stream.
  95. var input = new Stream_1.Stream(utilities_1.stringToCodePoints(opt_string));
  96. // 2. Let output be a new stream
  97. var output = [];
  98. /** @type {?(number|!Array.<number>)} */
  99. var result;
  100. // 3. While true, run these substeps:
  101. while (true) {
  102. // 1. Let token be the result of reading from input.
  103. var token = input.read();
  104. if (token === terminology_1.end_of_stream)
  105. break;
  106. // 2. Let result be the result of processing token for encoder,
  107. // input, output.
  108. result = this._encoder.handler(input, token);
  109. if (result === finished_1.finished)
  110. break;
  111. if (Array.isArray(result))
  112. output.push.apply(output, /**@type {!Array.<number>}*/ (result));
  113. else
  114. output.push(result);
  115. }
  116. // TODO: Align with spec algorithm.
  117. if (!this._do_not_flush) {
  118. while (true) {
  119. result = this._encoder.handler(input, input.read());
  120. if (result === finished_1.finished)
  121. break;
  122. if (Array.isArray(result))
  123. output.push.apply(output, /**@type {!Array.<number>}*/ (result));
  124. else
  125. output.push(result);
  126. }
  127. this._encoder = null;
  128. }
  129. // 3. If result is finished, convert output into a byte sequence,
  130. // and then return a Uint8Array object wrapping an ArrayBuffer
  131. // containing output.
  132. return new Uint8Array(output);
  133. };
  134. return TextEncoder;
  135. }());
  136. exports.TextEncoder = TextEncoder;
  137. //# sourceMappingURL=TextEncoder.js.map