binary-parser.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.BinaryParser = void 0;
  4. var assert = require("assert");
  5. var enums_1 = require("../enums");
  6. var buffer_1 = require("buffer/");
  7. /**
  8. * BinaryParser is used to compute fields and values from a HexString
  9. */
  10. var BinaryParser = /** @class */ (function () {
  11. /**
  12. * Initialize bytes to a hex string
  13. *
  14. * @param hexBytes a hex string
  15. */
  16. function BinaryParser(hexBytes) {
  17. this.bytes = buffer_1.Buffer.from(hexBytes, 'hex');
  18. }
  19. /**
  20. * Peek the first byte of the BinaryParser
  21. *
  22. * @returns The first byte of the BinaryParser
  23. */
  24. BinaryParser.prototype.peek = function () {
  25. assert.ok(this.bytes.byteLength !== 0);
  26. return this.bytes[0];
  27. };
  28. /**
  29. * Consume the first n bytes of the BinaryParser
  30. *
  31. * @param n the number of bytes to skip
  32. */
  33. BinaryParser.prototype.skip = function (n) {
  34. assert.ok(n <= this.bytes.byteLength);
  35. this.bytes = this.bytes.slice(n);
  36. };
  37. /**
  38. * read the first n bytes from the BinaryParser
  39. *
  40. * @param n The number of bytes to read
  41. * @return The bytes
  42. */
  43. BinaryParser.prototype.read = function (n) {
  44. assert.ok(n <= this.bytes.byteLength);
  45. var slice = this.bytes.slice(0, n);
  46. this.skip(n);
  47. return slice;
  48. };
  49. /**
  50. * Read an integer of given size
  51. *
  52. * @param n The number of bytes to read
  53. * @return The number represented by those bytes
  54. */
  55. BinaryParser.prototype.readUIntN = function (n) {
  56. assert.ok(0 < n && n <= 4, 'invalid n');
  57. return this.read(n).reduce(function (a, b) { return (a << 8) | b; }) >>> 0;
  58. };
  59. BinaryParser.prototype.readUInt8 = function () {
  60. return this.readUIntN(1);
  61. };
  62. BinaryParser.prototype.readUInt16 = function () {
  63. return this.readUIntN(2);
  64. };
  65. BinaryParser.prototype.readUInt32 = function () {
  66. return this.readUIntN(4);
  67. };
  68. BinaryParser.prototype.size = function () {
  69. return this.bytes.byteLength;
  70. };
  71. BinaryParser.prototype.end = function (customEnd) {
  72. var length = this.bytes.byteLength;
  73. return length === 0 || (customEnd !== undefined && length <= customEnd);
  74. };
  75. /**
  76. * Reads variable length encoded bytes
  77. *
  78. * @return The variable length bytes
  79. */
  80. BinaryParser.prototype.readVariableLength = function () {
  81. return this.read(this.readVariableLengthLength());
  82. };
  83. /**
  84. * Reads the length of the variable length encoded bytes
  85. *
  86. * @return The length of the variable length encoded bytes
  87. */
  88. BinaryParser.prototype.readVariableLengthLength = function () {
  89. var b1 = this.readUInt8();
  90. if (b1 <= 192) {
  91. return b1;
  92. }
  93. else if (b1 <= 240) {
  94. var b2 = this.readUInt8();
  95. return 193 + (b1 - 193) * 256 + b2;
  96. }
  97. else if (b1 <= 254) {
  98. var b2 = this.readUInt8();
  99. var b3 = this.readUInt8();
  100. return 12481 + (b1 - 241) * 65536 + b2 * 256 + b3;
  101. }
  102. throw new Error('Invalid variable length indicator');
  103. };
  104. /**
  105. * Reads the field ordinal from the BinaryParser
  106. *
  107. * @return Field ordinal
  108. */
  109. BinaryParser.prototype.readFieldOrdinal = function () {
  110. var type = this.readUInt8();
  111. var nth = type & 15;
  112. type >>= 4;
  113. if (type === 0) {
  114. type = this.readUInt8();
  115. if (type === 0 || type < 16) {
  116. throw new Error('Cannot read FieldOrdinal, type_code out of range');
  117. }
  118. }
  119. if (nth === 0) {
  120. nth = this.readUInt8();
  121. if (nth === 0 || nth < 16) {
  122. throw new Error('Cannot read FieldOrdinal, field_code out of range');
  123. }
  124. }
  125. return (type << 16) | nth;
  126. };
  127. /**
  128. * Read the field from the BinaryParser
  129. *
  130. * @return The field represented by the bytes at the head of the BinaryParser
  131. */
  132. BinaryParser.prototype.readField = function () {
  133. return enums_1.Field.fromString(this.readFieldOrdinal().toString());
  134. };
  135. /**
  136. * Read a given type from the BinaryParser
  137. *
  138. * @param type The type that you want to read from the BinaryParser
  139. * @return The instance of that type read from the BinaryParser
  140. */
  141. BinaryParser.prototype.readType = function (type) {
  142. return type.fromParser(this);
  143. };
  144. /**
  145. * Get the type associated with a given field
  146. *
  147. * @param field The field that you wan to get the type of
  148. * @return The type associated with the given field
  149. */
  150. BinaryParser.prototype.typeForField = function (field) {
  151. return field.associatedType;
  152. };
  153. /**
  154. * Read value of the type specified by field from the BinaryParser
  155. *
  156. * @param field The field that you want to get the associated value for
  157. * @return The value associated with the given field
  158. */
  159. BinaryParser.prototype.readFieldValue = function (field) {
  160. var type = this.typeForField(field);
  161. if (!type) {
  162. throw new Error("unsupported: (".concat(field.name, ", ").concat(field.type.name, ")"));
  163. }
  164. var sizeHint = field.isVariableLengthEncoded
  165. ? this.readVariableLengthLength()
  166. : undefined;
  167. var value = type.fromParser(this, sizeHint);
  168. if (value === undefined) {
  169. throw new Error("fromParser for (".concat(field.name, ", ").concat(field.type.name, ") -> undefined "));
  170. }
  171. return value;
  172. };
  173. /**
  174. * Get the next field and value from the BinaryParser
  175. *
  176. * @return The field and value
  177. */
  178. BinaryParser.prototype.readFieldAndValue = function () {
  179. var field = this.readField();
  180. return [field, this.readFieldValue(field)];
  181. };
  182. return BinaryParser;
  183. }());
  184. exports.BinaryParser = BinaryParser;
  185. //# sourceMappingURL=binary-parser.js.map