Spaces:
Sleeping
Sleeping
| var inherits = require('inherits'); | |
| var Reporter = require('../base').Reporter; | |
| var Buffer = require('buffer').Buffer; | |
| function DecoderBuffer(base, options) { | |
| Reporter.call(this, options); | |
| if (!Buffer.isBuffer(base)) { | |
| this.error('Input not Buffer'); | |
| return; | |
| } | |
| this.base = base; | |
| this.offset = 0; | |
| this.length = base.length; | |
| } | |
| inherits(DecoderBuffer, Reporter); | |
| exports.DecoderBuffer = DecoderBuffer; | |
| DecoderBuffer.prototype.save = function save() { | |
| return { offset: this.offset, reporter: Reporter.prototype.save.call(this) }; | |
| }; | |
| DecoderBuffer.prototype.restore = function restore(save) { | |
| // Return skipped data | |
| var res = new DecoderBuffer(this.base); | |
| res.offset = save.offset; | |
| res.length = this.offset; | |
| this.offset = save.offset; | |
| Reporter.prototype.restore.call(this, save.reporter); | |
| return res; | |
| }; | |
| DecoderBuffer.prototype.isEmpty = function isEmpty() { | |
| return this.offset === this.length; | |
| }; | |
| DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) { | |
| if (this.offset + 1 <= this.length) | |
| return this.base.readUInt8(this.offset++, true); | |
| else | |
| return this.error(fail || 'DecoderBuffer overrun'); | |
| } | |
| DecoderBuffer.prototype.skip = function skip(bytes, fail) { | |
| if (!(this.offset + bytes <= this.length)) | |
| return this.error(fail || 'DecoderBuffer overrun'); | |
| var res = new DecoderBuffer(this.base); | |
| // Share reporter state | |
| res._reporterState = this._reporterState; | |
| res.offset = this.offset; | |
| res.length = this.offset + bytes; | |
| this.offset += bytes; | |
| return res; | |
| } | |
| DecoderBuffer.prototype.raw = function raw(save) { | |
| return this.base.slice(save ? save.offset : this.offset, this.length); | |
| } | |
| function EncoderBuffer(value, reporter) { | |
| if (Array.isArray(value)) { | |
| this.length = 0; | |
| this.value = value.map(function(item) { | |
| if (!(item instanceof EncoderBuffer)) | |
| item = new EncoderBuffer(item, reporter); | |
| this.length += item.length; | |
| return item; | |
| }, this); | |
| } else if (typeof value === 'number') { | |
| if (!(0 <= value && value <= 0xff)) | |
| return reporter.error('non-byte EncoderBuffer value'); | |
| this.value = value; | |
| this.length = 1; | |
| } else if (typeof value === 'string') { | |
| this.value = value; | |
| this.length = Buffer.byteLength(value); | |
| } else if (Buffer.isBuffer(value)) { | |
| this.value = value; | |
| this.length = value.length; | |
| } else { | |
| return reporter.error('Unsupported type: ' + typeof value); | |
| } | |
| } | |
| exports.EncoderBuffer = EncoderBuffer; | |
| EncoderBuffer.prototype.join = function join(out, offset) { | |
| if (!out) | |
| out = new Buffer(this.length); | |
| if (!offset) | |
| offset = 0; | |
| if (this.length === 0) | |
| return out; | |
| if (Array.isArray(this.value)) { | |
| this.value.forEach(function(item) { | |
| item.join(out, offset); | |
| offset += item.length; | |
| }); | |
| } else { | |
| if (typeof this.value === 'number') | |
| out[offset] = this.value; | |
| else if (typeof this.value === 'string') | |
| out.write(this.value, offset); | |
| else if (Buffer.isBuffer(this.value)) | |
| this.value.copy(out, offset); | |
| offset += this.length; | |
| } | |
| return out; | |
| }; | |