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.

116 lines
3.0 KiB

4 years ago
  1. var inherits = require('inherits');
  2. var Reporter = require('../base').Reporter;
  3. var Buffer = require('buffer').Buffer;
  4. function DecoderBuffer(base, options) {
  5. Reporter.call(this, options);
  6. if (!Buffer.isBuffer(base)) {
  7. this.error('Input not Buffer');
  8. return;
  9. }
  10. this.base = base;
  11. this.offset = 0;
  12. this.length = base.length;
  13. }
  14. inherits(DecoderBuffer, Reporter);
  15. exports.DecoderBuffer = DecoderBuffer;
  16. DecoderBuffer.prototype.save = function save() {
  17. return { offset: this.offset, reporter: Reporter.prototype.save.call(this) };
  18. };
  19. DecoderBuffer.prototype.restore = function restore(save) {
  20. // Return skipped data
  21. var res = new DecoderBuffer(this.base);
  22. res.offset = save.offset;
  23. res.length = this.offset;
  24. this.offset = save.offset;
  25. Reporter.prototype.restore.call(this, save.reporter);
  26. return res;
  27. };
  28. DecoderBuffer.prototype.isEmpty = function isEmpty() {
  29. return this.offset === this.length;
  30. };
  31. DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) {
  32. if (this.offset + 1 <= this.length)
  33. return this.base.readUInt8(this.offset++, true);
  34. else
  35. return this.error(fail || 'DecoderBuffer overrun');
  36. }
  37. DecoderBuffer.prototype.skip = function skip(bytes, fail) {
  38. if (!(this.offset + bytes <= this.length))
  39. return this.error(fail || 'DecoderBuffer overrun');
  40. var res = new DecoderBuffer(this.base);
  41. // Share reporter state
  42. res._reporterState = this._reporterState;
  43. res.offset = this.offset;
  44. res.length = this.offset + bytes;
  45. this.offset += bytes;
  46. return res;
  47. }
  48. DecoderBuffer.prototype.raw = function raw(save) {
  49. return this.base.slice(save ? save.offset : this.offset, this.length);
  50. }
  51. function EncoderBuffer(value, reporter) {
  52. if (Array.isArray(value)) {
  53. this.length = 0;
  54. this.value = value.map(function(item) {
  55. if (!(item instanceof EncoderBuffer))
  56. item = new EncoderBuffer(item, reporter);
  57. this.length += item.length;
  58. return item;
  59. }, this);
  60. } else if (typeof value === 'number') {
  61. if (!(0 <= value && value <= 0xff))
  62. return reporter.error('non-byte EncoderBuffer value');
  63. this.value = value;
  64. this.length = 1;
  65. } else if (typeof value === 'string') {
  66. this.value = value;
  67. this.length = Buffer.byteLength(value);
  68. } else if (Buffer.isBuffer(value)) {
  69. this.value = value;
  70. this.length = value.length;
  71. } else {
  72. return reporter.error('Unsupported type: ' + typeof value);
  73. }
  74. }
  75. exports.EncoderBuffer = EncoderBuffer;
  76. EncoderBuffer.prototype.join = function join(out, offset) {
  77. if (!out)
  78. out = new Buffer(this.length);
  79. if (!offset)
  80. offset = 0;
  81. if (this.length === 0)
  82. return out;
  83. if (Array.isArray(this.value)) {
  84. this.value.forEach(function(item) {
  85. item.join(out, offset);
  86. offset += item.length;
  87. });
  88. } else {
  89. if (typeof this.value === 'number')
  90. out[offset] = this.value;
  91. else if (typeof this.value === 'string')
  92. out.write(this.value, offset);
  93. else if (Buffer.isBuffer(this.value))
  94. this.value.copy(out, offset);
  95. offset += this.length;
  96. }
  97. return out;
  98. };