UNPKG

cbor

Version:

Encode and parse CBOR documents.

376 lines (326 loc) 10.9 kB
(function() { var BufferStream, EMPTY, assert, createEOF, stream, util, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __slice = [].slice; assert = require('assert'); util = require('util'); stream = require('stream'); EMPTY = new Buffer(0); createEOF = function() { var e; e = new Error('EOF'); e.BufferStreamEOF = true; return e; }; BufferStream = (function(_super) { __extends(BufferStream, _super); function BufferStream(options) { var buf, startEnded, _ref, _ref1, _ref2; if (options == null) { options = {}; } this.clear(); this._resetCB(); BufferStream.__super__.constructor.call(this, options); this.growSize = (_ref = options.bsGrowSize) != null ? _ref : 512; this.zero = (_ref1 = options.bsZero) != null ? _ref1 : false; this.on("finish", (function(_this) { return function() { return _this._resetCB(createEOF()); }; })(this)); buf = options.bsInit; if (Buffer.isBuffer(buf)) { this.append(buf); startEnded = (_ref2 = options.bsStartEnded) != null ? _ref2 : true; if (!!startEnded) { this.end(); } } else if (!options.bsStartEmpty) { this.grow(); } } BufferStream.isBufferStream = function(obj) { return obj instanceof BufferStream; }; BufferStream.isEOFError = function(er) { return er && (er instanceof Error) && (er.BufferStreamEOF === true); }; BufferStream.prototype.encodeCBOR = function(enc) { return enc._packBuffer(enc, this.flatten()); }; BufferStream.prototype.isValid = function() { var len; len = this.bufs.reduce(function(prev, cur) { return prev + cur.length; }, 0); len -= this.left; return len === this.length; }; BufferStream.prototype._bufSizes = function() { return this.bufs.map(function(b) { return b.length; }); }; BufferStream.prototype._write = function(chunk, encoding, cb) { if (!Buffer.isBuffer(chunk)) { return cb(new Error('String encoding not supported')); } else { this.append(chunk); return cb(); } }; BufferStream.prototype._resetCB = function() { var args, cb, _ref; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; _ref = [this.waitingCB, null, Number.MAX_VALUE], cb = _ref[0], this.waitingCB = _ref[1], this.waitingLen = _ref[2]; if (cb && args.length) { cb.apply(this, args); } return cb; }; BufferStream.prototype._notifyWaiter = function() { var buf; assert.ok(this.waitingCB); buf = this.read(this.waitingLen); return this._resetCB(null, buf); }; BufferStream.prototype.read = function(length) { var b, buf, got, last, lastbuf, left, lenW, lenZ, local_left, some; buf = null; if (this.length === 0) { return EMPTY; } lenZ = this.bufs[0].length; if (length == null) { length = 0; } lenW = (function() { switch (length) { case 0: return this.length; case -1: return Math.min(this.length, lenZ); default: return Math.min(this.length, length); } }).call(this); if (lenZ === lenW) { buf = this.bufs.shift(); } else if (lenZ > lenW) { buf = this.bufs[0].slice(0, lenW); this.bufs[0] = this.bufs[0].slice(lenW); } else if (lenW === this.length) { local_left = null; if (this.left !== 0) { lastbuf = this.bufs[this.bufs.length - 1]; if (this.left === lastbuf.length) { local_left = this.bufs.pop(); } else { local_left = lastbuf.slice(lastbuf.length - this.left); } } buf = Buffer.concat(this.bufs, this.length); this.bufs = local_left ? [local_left] : []; } else { some = []; got = 0; while (got < lenW) { b = this.bufs.shift(); some.push(b); got += b.length; } buf = Buffer.concat(some, lenW); if (got > lenW) { last = some[some.length - 1]; left = got - lenW; this.bufs.unshift(last.slice(last.length - left)); } } this.length -= lenW; return buf; }; BufferStream.prototype.isEOF = function() { return (this.length === 0) && this._writableState.finished; }; BufferStream.prototype.wait = function(length, cb) { if (this.waitingCB) { throw new Error('Invalid state. Cannot wait while already waiting.'); } if (!((typeof length === 'number') && (length >= 0))) { throw new Error("length required, must be non-negative number: " + length); } if (typeof cb !== 'function') { throw new Error('cb required, must be function'); } if (length === 0) { return process.nextTick((function(_this) { return function() { return cb.call(_this, null, EMPTY); }; })(this)); } else { this.waitingCB = cb; this.waitingLen = length; if (this.length >= length) { return this._notifyWaiter(); } else if (this._writableState.ended) { return this._resetCB(createEOF()); } } }; BufferStream.prototype.clear = function() { this.bufs = []; this.length = 0; return this.left = 0; }; BufferStream.prototype._trimLast = function() { var last, old; old = this.left; if (this.left > 0) { last = this.bufs.pop(); if (this.left !== last.length) { this.bufs.push(last.slice(0, last.length - this.left)); } this.left = 0; } return old; }; BufferStream.prototype._lengthen = function(size) { var len; assert.ok(size > 0); this.length += size; len = this.length; if (this.length >= this.waitingLen) { this._notifyWaiter(); } return len; }; BufferStream.prototype.grow = function(size) { var b, s; this._trimLast(); s = size != null ? size : this.growSize; b = new Buffer(s); if (this.zero) { b.fill(0); } this.bufs.push(b); this.left = s; return b; }; BufferStream.prototype.append = function(buf) { var lastbuf, len; assert.ok(Buffer.isBuffer(buf)); len = buf.length; if (len === 0) { return; } if (this.left === 0) { this.bufs.push(buf); } else if (len > this.left) { this._trimLast(); this.bufs.push(buf); } else { lastbuf = this.bufs[this.bufs.length - 1]; buf.copy(lastbuf, lastbuf.length - this.left); this.left -= len; } return this._lengthen(len); }; BufferStream.prototype.flatten = function() { var b; if (this.length === 0) { this.left = 0; this.bufs = []; return EMPTY; } b = null; switch (this.bufs.length) { case 0: assert.fail(this.length, "Invalid state. No buffers when length>0."); break; case 1: if (this.left === 0) { b = this.bufs[0]; } else { b = this.bufs[0].slice(0, this.length); this.bufs = [b]; this.left = 0; } break; default: if (this.left === this.bufs[this.bufs.length - 1].length) { this.bufs.pop(); } b = Buffer.concat(this.bufs, this.length); this.bufs = [b]; this.left = 0; } return b; }; BufferStream.prototype.slice = function(start, end) { return this.flatten().slice(start, end); }; BufferStream.prototype.fill = function(val, offset, end) { return this.flatten().fill(val, offset, end); }; BufferStream.prototype.toJSON = function() { return this.flatten().toJSON(); }; BufferStream.prototype.toString = function(encoding) { if (encoding == null) { encoding = 'hex'; } return this.flatten().toString(encoding); }; BufferStream.prototype.ensure = function(len) { if (this.left < len) { return this.grow(Math.max(this.growSize, len)); } else { return this.bufs[this.bufs.length - 1]; } }; BufferStream.prototype.writeString = function(value, length, encoding) { var b; if (encoding == null) { encoding = 'utf8'; } if (length == null) { length = Buffer.byteLength(value, encoding); } if (length === 0) { return; } b = this.ensure(length); b.write(value, b.length - this.left, length, encoding); this.left -= length; return this._lengthen(length); }; BufferStream._write_gen = function(meth, len) { return function(val) { var b; b = this.ensure(len); b[meth].call(b, val, b.length - this.left, true); this.left -= len; return this._lengthen(len); }; }; BufferStream.prototype.writeUInt8 = BufferStream._write_gen('writeUInt8', 1); BufferStream.prototype.writeUInt16LE = BufferStream._write_gen('writeUInt16LE', 2); BufferStream.prototype.writeUInt16BE = BufferStream._write_gen('writeUInt16BE', 2); BufferStream.prototype.writeUInt32LE = BufferStream._write_gen('writeUInt32LE', 4); BufferStream.prototype.writeUInt32BE = BufferStream._write_gen('writeUInt32BE', 4); BufferStream.prototype.writeInt8 = BufferStream._write_gen('writeInt8', 1); BufferStream.prototype.writeInt16LE = BufferStream._write_gen('writeInt16LE', 2); BufferStream.prototype.writeInt16BE = BufferStream._write_gen('writeInt16BE', 2); BufferStream.prototype.writeInt32LE = BufferStream._write_gen('writeInt32LE', 4); BufferStream.prototype.writeInt32BE = BufferStream._write_gen('writeInt32BE', 4); BufferStream.prototype.writeFloatLE = BufferStream._write_gen('writeFloatLE', 4); BufferStream.prototype.writeFloatBE = BufferStream._write_gen('writeFloatBE', 4); BufferStream.prototype.writeDoubleLE = BufferStream._write_gen('writeDoubleLE', 8); BufferStream.prototype.writeDoubleBE = BufferStream._write_gen('writeDoubleBE', 8); return BufferStream; })(stream.Writable); module.exports = BufferStream; }).call(this);