BencodeDecoder.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.BencodeDecoder = void 0;
  4. const Reader_1 = require("@jsonjoy.com/util/lib/buffers/Reader");
  5. class BencodeDecoder {
  6. constructor() {
  7. this.reader = new Reader_1.Reader();
  8. }
  9. read(uint8) {
  10. this.reader.reset(uint8);
  11. return this.readAny();
  12. }
  13. decode(uint8) {
  14. this.reader.reset(uint8);
  15. return this.readAny();
  16. }
  17. readAny() {
  18. const reader = this.reader;
  19. const x = reader.x;
  20. const uint8 = reader.uint8;
  21. const char = uint8[x];
  22. switch (char) {
  23. case 0x69:
  24. return this.readNum();
  25. case 0x64:
  26. return this.readObj();
  27. case 0x6c:
  28. return this.readArr();
  29. case 0x66:
  30. return this.readFalse();
  31. case 0x74:
  32. return this.readTrue();
  33. case 110:
  34. return this.readNull();
  35. case 117:
  36. return this.readUndef();
  37. default:
  38. if (char >= 48 && char <= 57)
  39. return this.readBin();
  40. }
  41. throw new Error('INVALID_BENCODE');
  42. }
  43. readNull() {
  44. if (this.reader.u8() !== 0x6e)
  45. throw new Error('INVALID_BENCODE');
  46. return null;
  47. }
  48. readUndef() {
  49. if (this.reader.u8() !== 117)
  50. throw new Error('INVALID_BENCODE');
  51. return undefined;
  52. }
  53. readTrue() {
  54. if (this.reader.u8() !== 0x74)
  55. throw new Error('INVALID_BENCODE');
  56. return true;
  57. }
  58. readFalse() {
  59. if (this.reader.u8() !== 0x66)
  60. throw new Error('INVALID_BENCODE');
  61. return false;
  62. }
  63. readBool() {
  64. const reader = this.reader;
  65. switch (reader.uint8[reader.x]) {
  66. case 0x66:
  67. return this.readFalse();
  68. case 0x74:
  69. return this.readTrue();
  70. default:
  71. throw new Error('INVALID_BENCODE');
  72. }
  73. }
  74. readNum() {
  75. const reader = this.reader;
  76. const startChar = reader.u8();
  77. if (startChar !== 0x69)
  78. throw new Error('INVALID_BENCODE');
  79. const u8 = reader.uint8;
  80. let x = reader.x;
  81. let numStr = '';
  82. let c = u8[x++];
  83. let i = 0;
  84. while (c !== 0x65) {
  85. numStr += String.fromCharCode(c);
  86. c = u8[x++];
  87. if (i > 25)
  88. throw new Error('INVALID_BENCODE');
  89. i++;
  90. }
  91. if (!numStr)
  92. throw new Error('INVALID_BENCODE');
  93. reader.x = x;
  94. return +numStr;
  95. }
  96. readStr() {
  97. const bin = this.readBin();
  98. return new TextDecoder().decode(bin);
  99. }
  100. readBin() {
  101. const reader = this.reader;
  102. const u8 = reader.uint8;
  103. let lenStr = '';
  104. let x = reader.x;
  105. let c = u8[x++];
  106. let i = 0;
  107. while (c !== 0x3a) {
  108. if (c < 48 || c > 57)
  109. throw new Error('INVALID_BENCODE');
  110. lenStr += String.fromCharCode(c);
  111. c = u8[x++];
  112. if (i > 10)
  113. throw new Error('INVALID_BENCODE');
  114. i++;
  115. }
  116. reader.x = x;
  117. const len = +lenStr;
  118. const bin = reader.buf(len);
  119. return bin;
  120. }
  121. readArr() {
  122. const reader = this.reader;
  123. if (reader.u8() !== 0x6c)
  124. throw new Error('INVALID_BENCODE');
  125. const arr = [];
  126. const uint8 = reader.uint8;
  127. while (true) {
  128. const char = uint8[reader.x];
  129. if (char === 0x65) {
  130. reader.x++;
  131. return arr;
  132. }
  133. arr.push(this.readAny());
  134. }
  135. }
  136. readObj() {
  137. const reader = this.reader;
  138. if (reader.u8() !== 0x64)
  139. throw new Error('INVALID_BENCODE');
  140. const obj = {};
  141. const uint8 = reader.uint8;
  142. while (true) {
  143. const char = uint8[reader.x];
  144. if (char === 0x65) {
  145. reader.x++;
  146. return obj;
  147. }
  148. const key = this.readStr();
  149. if (key === '__proto__')
  150. throw new Error('INVALID_KEY');
  151. obj[key] = this.readAny();
  152. }
  153. }
  154. }
  155. exports.BencodeDecoder = BencodeDecoder;
  156. //# sourceMappingURL=BencodeDecoder.js.map