ISO2022JPEncoder.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. var encodings_1 = require("../../encoding/encodings");
  4. var finished_1 = require("../../encoding/finished");
  5. var indexes_1 = require("../../encoding/indexes");
  6. var terminology_1 = require("../../encoding/terminology");
  7. var states;
  8. (function (states) {
  9. states[states["ASCII"] = 0] = "ASCII";
  10. states[states["Roman"] = 1] = "Roman";
  11. states[states["jis0208"] = 2] = "jis0208";
  12. })(states || (states = {}));
  13. /**
  14. * @constructor
  15. * @implements {Encoder}
  16. * @param {{fatal: boolean}} options
  17. */
  18. var ISO2022JPEncoder = /** @class */ (function () {
  19. function ISO2022JPEncoder(options) {
  20. this.fatal = options.fatal;
  21. // iso-2022-jp's encoder has an associated iso-2022-jp encoder
  22. // state which is one of ASCII, Roman, and jis0208 (initially
  23. // ASCII).
  24. /** @type {number} */ this.iso2022jp_state = states.ASCII;
  25. }
  26. /**
  27. * @param {Stream} stream Input stream.
  28. * @param {number} code_point Next code point read from the stream.
  29. * @return {(number|!Array.<number>)} Byte(s) to emit.
  30. */
  31. ISO2022JPEncoder.prototype.handler = function (stream, code_point) {
  32. // 1. If code point is end-of-stream and iso-2022-jp encoder
  33. // state is not ASCII, prepend code point to stream, set
  34. // iso-2022-jp encoder state to ASCII, and return three bytes
  35. // 0x1B 0x28 0x42.
  36. if (code_point === terminology_1.end_of_stream &&
  37. this.iso2022jp_state !== states.ASCII) {
  38. stream.prepend(code_point);
  39. this.iso2022jp_state = states.ASCII;
  40. return [0x1B, 0x28, 0x42];
  41. }
  42. // 2. If code point is end-of-stream and iso-2022-jp encoder
  43. // state is ASCII, return finished.
  44. if (code_point === terminology_1.end_of_stream && this.iso2022jp_state === states.ASCII)
  45. return finished_1.finished;
  46. // 3. If ISO-2022-JP encoder state is ASCII or Roman, and code
  47. // point is U+000E, U+000F, or U+001B, return error with U+FFFD.
  48. if ((this.iso2022jp_state === states.ASCII ||
  49. this.iso2022jp_state === states.Roman) &&
  50. (code_point === 0x000E || code_point === 0x000F ||
  51. code_point === 0x001B)) {
  52. return encodings_1.encoderError(0xFFFD);
  53. }
  54. // 4. If iso-2022-jp encoder state is ASCII and code point is an
  55. // ASCII code point, return a byte whose value is code point.
  56. if (this.iso2022jp_state === states.ASCII &&
  57. terminology_1.isASCIICodePoint(code_point))
  58. return code_point;
  59. // 5. If iso-2022-jp encoder state is Roman and code point is an
  60. // ASCII code point, excluding U+005C and U+007E, or is U+00A5
  61. // or U+203E, run these substeps:
  62. if (this.iso2022jp_state === states.Roman &&
  63. ((terminology_1.isASCIICodePoint(code_point) &&
  64. code_point !== 0x005C && code_point !== 0x007E) ||
  65. (code_point == 0x00A5 || code_point == 0x203E))) {
  66. // 1. If code point is an ASCII code point, return a byte
  67. // whose value is code point.
  68. if (terminology_1.isASCIICodePoint(code_point))
  69. return code_point;
  70. // 2. If code point is U+00A5, return byte 0x5C.
  71. if (code_point === 0x00A5)
  72. return 0x5C;
  73. // 3. If code point is U+203E, return byte 0x7E.
  74. if (code_point === 0x203E)
  75. return 0x7E;
  76. }
  77. // 6. If code point is an ASCII code point, and iso-2022-jp
  78. // encoder state is not ASCII, prepend code point to stream, set
  79. // iso-2022-jp encoder state to ASCII, and return three bytes
  80. // 0x1B 0x28 0x42.
  81. if (terminology_1.isASCIICodePoint(code_point) &&
  82. this.iso2022jp_state !== states.ASCII) {
  83. stream.prepend(code_point);
  84. this.iso2022jp_state = states.ASCII;
  85. return [0x1B, 0x28, 0x42];
  86. }
  87. // 7. If code point is either U+00A5 or U+203E, and iso-2022-jp
  88. // encoder state is not Roman, prepend code point to stream, set
  89. // iso-2022-jp encoder state to Roman, and return three bytes
  90. // 0x1B 0x28 0x4A.
  91. if ((code_point === 0x00A5 || code_point === 0x203E) &&
  92. this.iso2022jp_state !== states.Roman) {
  93. stream.prepend(code_point);
  94. this.iso2022jp_state = states.Roman;
  95. return [0x1B, 0x28, 0x4A];
  96. }
  97. // 8. If code point is U+2212, set it to U+FF0D.
  98. if (code_point === 0x2212)
  99. code_point = 0xFF0D;
  100. // 9. Let pointer be the index pointer for code point in index
  101. // jis0208.
  102. var pointer = indexes_1.indexPointerFor(code_point, indexes_1.index('jis0208'));
  103. // 10. If pointer is null, return error with code point.
  104. if (pointer === null)
  105. return encodings_1.encoderError(code_point);
  106. // 11. If iso-2022-jp encoder state is not jis0208, prepend code
  107. // point to stream, set iso-2022-jp encoder state to jis0208,
  108. // and return three bytes 0x1B 0x24 0x42.
  109. if (this.iso2022jp_state !== states.jis0208) {
  110. stream.prepend(code_point);
  111. this.iso2022jp_state = states.jis0208;
  112. return [0x1B, 0x24, 0x42];
  113. }
  114. // 12. Let lead be Math.floor(pointer / 94) + 0x21.
  115. var lead = Math.floor(pointer / 94) + 0x21;
  116. // 13. Let trail be pointer % 94 + 0x21.
  117. var trail = pointer % 94 + 0x21;
  118. // 14. Return two bytes whose values are lead and trail.
  119. return [lead, trail];
  120. };
  121. return ISO2022JPEncoder;
  122. }());
  123. exports.ISO2022JPEncoder = ISO2022JPEncoder;
  124. //# sourceMappingURL=ISO2022JPEncoder.js.map