You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

frame.js 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. 'use strict';
  2. const assert = require('bsert');
  3. const DUMMY = Buffer.alloc(0);
  4. const types = {
  5. OPEN: 0,
  6. CLOSE: 1,
  7. PING: 2,
  8. PONG: 3,
  9. MESSAGE: 4,
  10. UPGRADE: 5,
  11. NOOP: 6
  12. };
  13. const table = [
  14. 'open',
  15. 'close',
  16. 'ping',
  17. 'pong',
  18. 'message',
  19. 'upgrade',
  20. 'noop'
  21. ];
  22. class Frame {
  23. constructor(type, data, binary) {
  24. assert(typeof type === 'number');
  25. assert((type >>> 0) === type);
  26. assert(type <= types.NOOP);
  27. assert(typeof binary === 'boolean');
  28. if (binary) {
  29. if (data == null)
  30. data = DUMMY;
  31. assert(Buffer.isBuffer(data));
  32. } else {
  33. if (data == null)
  34. data = '';
  35. assert(typeof data === 'string');
  36. }
  37. this.type = type;
  38. this.data = data;
  39. this.binary = binary;
  40. }
  41. toString() {
  42. let str = '';
  43. if (this.binary) {
  44. str += 'b';
  45. str += this.type.toString(10);
  46. str += this.data.toString('base64');
  47. } else {
  48. str += this.type.toString(10);
  49. str += this.data;
  50. }
  51. return str;
  52. }
  53. static fromString(str) {
  54. assert(typeof str === 'string');
  55. let type = str.charCodeAt(0);
  56. let binary = false;
  57. let data;
  58. // 'b' - base64
  59. if (type === 0x62) {
  60. assert(str.length > 1);
  61. type = str.charCodeAt(1);
  62. data = Buffer.from(str.substring(2), 'base64');
  63. binary = true;
  64. } else {
  65. data = str.substring(1);
  66. }
  67. type -= 0x30;
  68. assert(type >= 0 && type <= 9);
  69. assert(type <= types.NOOP);
  70. return new this(type, data, binary);
  71. }
  72. size() {
  73. let len = 1;
  74. if (this.binary)
  75. len += this.data.length;
  76. else
  77. len += Buffer.byteLength(this.data, 'utf8');
  78. return len;
  79. }
  80. toRaw() {
  81. const data = Buffer.allocUnsafe(this.size());
  82. data[0] = this.type;
  83. if (this.binary) {
  84. this.data.copy(data, 1);
  85. } else {
  86. if (this.data.length > 0)
  87. data.write(this.data, 1, 'utf8');
  88. }
  89. return data;
  90. }
  91. static fromRaw(data) {
  92. assert(Buffer.isBuffer(data));
  93. assert(data.length > 0);
  94. const type = data[0];
  95. assert(type <= types.NOOP);
  96. return new this(type, data.slice(1), true);
  97. }
  98. }
  99. Frame.types = types;
  100. Frame.table = table;
  101. module.exports = Frame;