WsFrameEncoder.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.WsFrameEncoder = void 0;
  4. const Writer_1 = require("@jsonjoy.com/util/lib/buffers/Writer");
  5. const constants_1 = require("./constants");
  6. const errors_1 = require("./errors");
  7. const maskBuf = new Uint8Array(4);
  8. const maskBufView = new DataView(maskBuf.buffer, maskBuf.byteOffset, maskBuf.byteLength);
  9. class WsFrameEncoder {
  10. constructor(writer = new Writer_1.Writer()) {
  11. this.writer = writer;
  12. }
  13. encodePing(data) {
  14. this.writePing(data);
  15. return this.writer.flush();
  16. }
  17. encodePong(data) {
  18. this.writePong(data);
  19. return this.writer.flush();
  20. }
  21. encodeClose(reason, code = 0) {
  22. this.writeClose(reason, code);
  23. return this.writer.flush();
  24. }
  25. encodeHdr(fin, opcode, length, mask) {
  26. this.writeHdr(fin, opcode, length, mask);
  27. return this.writer.flush();
  28. }
  29. encodeDataMsgHdrFast(length) {
  30. this.writeDataMsgHdrFast(length);
  31. return this.writer.flush();
  32. }
  33. writePing(data) {
  34. let length = 0;
  35. if (data && (length = data.length)) {
  36. this.writeHdr(1, constants_1.WsFrameOpcode.PING, length, 0);
  37. this.writer.buf(data, length);
  38. }
  39. else {
  40. this.writeHdr(1, constants_1.WsFrameOpcode.PING, 0, 0);
  41. }
  42. }
  43. writePong(data) {
  44. let length = 0;
  45. if (data && (length = data.length)) {
  46. this.writeHdr(1, constants_1.WsFrameOpcode.PONG, length, 0);
  47. this.writer.buf(data, length);
  48. }
  49. else {
  50. this.writeHdr(1, constants_1.WsFrameOpcode.PONG, 0, 0);
  51. }
  52. }
  53. writeClose(reason, code = 0) {
  54. if (reason || code) {
  55. const reasonLength = reason.length;
  56. const length = 2 + reasonLength;
  57. const writer = this.writer;
  58. writer.ensureCapacity(2 +
  59. 2 +
  60. reasonLength * 4);
  61. const lengthX = writer.x + 1;
  62. this.writeHdr(1, constants_1.WsFrameOpcode.CLOSE, length, 0);
  63. writer.u16(code);
  64. if (reasonLength) {
  65. const utf8Length = writer.utf8(reason);
  66. if (utf8Length !== reasonLength) {
  67. if (utf8Length > 126 - 2)
  68. throw new errors_1.WsFrameEncodingError();
  69. writer.uint8[lengthX] = (writer.uint8[lengthX] & 0b10000000) | (utf8Length + 2);
  70. }
  71. }
  72. }
  73. else {
  74. this.writeHdr(1, constants_1.WsFrameOpcode.CLOSE, 0, 0);
  75. }
  76. }
  77. writeHdr(fin, opcode, length, mask) {
  78. const octet1 = (fin << 7) | opcode;
  79. const maskBit = mask ? 0b10000000 : 0b00000000;
  80. const writer = this.writer;
  81. if (length < 126) {
  82. const octet2 = maskBit | length;
  83. writer.u16((octet1 << 8) | octet2);
  84. }
  85. else if (length < 0x10000) {
  86. const octet2 = maskBit | 126;
  87. writer.u32(((octet1 << 8) | octet2) * 0x10000 + length);
  88. }
  89. else {
  90. const octet2 = maskBit | 127;
  91. writer.u16((octet1 << 8) | octet2);
  92. writer.u32(0);
  93. writer.u32(length);
  94. }
  95. if (mask)
  96. writer.u32(mask);
  97. }
  98. writeDataMsgHdrFast(length) {
  99. const writer = this.writer;
  100. if (length < 126) {
  101. writer.u16(33280 + length);
  102. return;
  103. }
  104. if (length < 0x10000) {
  105. writer.u32(2189295616 + length);
  106. return;
  107. }
  108. writer.u16(33407);
  109. writer.u32(0);
  110. writer.u32(length);
  111. }
  112. writeBufXor(buf, mask) {
  113. maskBufView.setUint32(0, mask, false);
  114. const writer = this.writer;
  115. const length = buf.length;
  116. writer.ensureCapacity(length);
  117. let x = writer.x;
  118. const uint8 = writer.uint8;
  119. for (let i = 0; i < length; i++)
  120. uint8[x++] = buf[i] ^ maskBuf[i & 3];
  121. writer.x = x;
  122. }
  123. }
  124. exports.WsFrameEncoder = WsFrameEncoder;
  125. //# sourceMappingURL=WsFrameEncoder.js.map