diff --git a/lib/bufferish-array.js b/lib/bufferish-array.js deleted file mode 100644 index 914271e..0000000 --- a/lib/bufferish-array.js +++ /dev/null @@ -1,41 +0,0 @@ -// bufferish-array.js - -var Bufferish = require("./bufferish"); - -var exports = module.exports = alloc(0); - -exports.alloc = alloc; -exports.concat = Bufferish.concat; -exports.from = from; - -/** - * @param size {Number} - * @returns {Buffer|Uint8Array|Array} - */ - -function alloc(size) { - return new Array(size); -} - -/** - * @param value {Array|ArrayBuffer|Buffer|String} - * @returns {Array} - */ - -function from(value) { - if (!Bufferish.isBuffer(value) && Bufferish.isView(value)) { - // TypedArray to Uint8Array - value = Bufferish.Uint8Array.from(value); - } else if (Bufferish.isArrayBuffer(value)) { - // ArrayBuffer to Uint8Array - value = new Uint8Array(value); - } else if (typeof value === "string") { - // String to Array - return Bufferish.from.call(exports, value); - } else if (typeof value === "number") { - throw new TypeError('"value" argument must not be a number'); - } - - // Array-like to Array - return Array.prototype.slice.call(value); -} diff --git a/lib/bufferish-buffer.js b/lib/bufferish-buffer.js deleted file mode 100644 index abbd985..0000000 --- a/lib/bufferish-buffer.js +++ /dev/null @@ -1,46 +0,0 @@ -// bufferish-buffer.js - -var Bufferish = require("./bufferish"); -var Buffer = Bufferish.global; - -var exports = module.exports = Bufferish.hasBuffer ? alloc(0) : []; - -exports.alloc = Bufferish.hasBuffer && Buffer.alloc || alloc; -exports.concat = Bufferish.concat; -exports.from = from; - -/** - * @param size {Number} - * @returns {Buffer|Uint8Array|Array} - */ - -function alloc(size) { - return new Buffer(size); -} - -/** - * @param value {Array|ArrayBuffer|Buffer|String} - * @returns {Buffer} - */ - -function from(value) { - if (!Bufferish.isBuffer(value) && Bufferish.isView(value)) { - // TypedArray to Uint8Array - value = Bufferish.Uint8Array.from(value); - } else if (Bufferish.isArrayBuffer(value)) { - // ArrayBuffer to Uint8Array - value = new Uint8Array(value); - } else if (typeof value === "string") { - // String to Buffer - return Bufferish.from.call(exports, value); - } else if (typeof value === "number") { - throw new TypeError('"value" argument must not be a number'); - } - - // Array-like to Buffer - if (Buffer.from && Buffer.from.length !== 1) { - return Buffer.from(value); // node v6+ - } else { - return new Buffer(value); // node v4 - } -} diff --git a/lib/bufferish-proto.js b/lib/bufferish-proto.js deleted file mode 100644 index 41c6e0d..0000000 --- a/lib/bufferish-proto.js +++ /dev/null @@ -1,86 +0,0 @@ -// bufferish-proto.js - -/* jshint eqnull:true */ - -var BufferLite = require("./buffer-lite"); - -exports.copy = copy; -exports.slice = slice; -exports.toString = toString; -exports.write = gen("write"); - -var Bufferish = require("./bufferish"); -var Buffer = Bufferish.global; - -var isBufferShim = Bufferish.hasBuffer && ("TYPED_ARRAY_SUPPORT" in Buffer); -var brokenTypedArray = isBufferShim && !Buffer.TYPED_ARRAY_SUPPORT; - -/** - * @param target {Buffer|Uint8Array|Array} - * @param [targetStart] {Number} - * @param [start] {Number} - * @param [end] {Number} - * @returns {Buffer|Uint8Array|Array} - */ - -function copy(target, targetStart, start, end) { - var thisIsBuffer = Bufferish.isBuffer(this); - var targetIsBuffer = Bufferish.isBuffer(target); - if (thisIsBuffer && targetIsBuffer) { - // Buffer to Buffer - return this.copy(target, targetStart, start, end); - } else if (!brokenTypedArray && !thisIsBuffer && !targetIsBuffer && - Bufferish.isView(this) && Bufferish.isView(target)) { - // Uint8Array to Uint8Array (except for minor some browsers) - var buffer = (start || end != null) ? slice.call(this, start, end) : this; - target.set(buffer, targetStart); - return buffer.length; - } else { - // other cases - return BufferLite.copy.call(this, target, targetStart, start, end); - } -} - -/** - * @param [start] {Number} - * @param [end] {Number} - * @returns {Buffer|Uint8Array|Array} - */ - -function slice(start, end) { - // for Buffer, Uint8Array (except for minor some browsers) and Array - var f = this.slice || (!brokenTypedArray && this.subarray); - if (f) return f.call(this, start, end); - - // Uint8Array (for minor some browsers) - var target = Bufferish.alloc.call(this, end - start); - copy.call(this, target, 0, start, end); - return target; -} - -/** - * Buffer.prototype.toString() - * - * @param [encoding] {String} ignored - * @param [start] {Number} - * @param [end] {Number} - * @returns {String} - */ - -function toString(encoding, start, end) { - var f = (!isBufferShim && Bufferish.isBuffer(this)) ? this.toString : BufferLite.toString; - return f.apply(this, arguments); -} - -/** - * @private - */ - -function gen(method) { - return wrap; - - function wrap() { - var f = this[method] || BufferLite[method]; - return f.apply(this, arguments); - } -} diff --git a/lib/bufferish-uint8array.js b/lib/bufferish-uint8array.js deleted file mode 100644 index 03bca61..0000000 --- a/lib/bufferish-uint8array.js +++ /dev/null @@ -1,51 +0,0 @@ -// bufferish-uint8array.js - -var Bufferish = require("./bufferish"); - -var exports = module.exports = Bufferish.hasArrayBuffer ? alloc(0) : []; - -exports.alloc = alloc; -exports.concat = Bufferish.concat; -exports.from = from; - -/** - * @param size {Number} - * @returns {Buffer|Uint8Array|Array} - */ - -function alloc(size) { - return new Uint8Array(size); -} - -/** - * @param value {Array|ArrayBuffer|Buffer|String} - * @returns {Uint8Array} - */ - -function from(value) { - if (Bufferish.isView(value)) { - // TypedArray to ArrayBuffer - var byteOffset = value.byteOffset; - var byteLength = value.byteLength; - value = value.buffer; - if (value.byteLength !== byteLength) { - if (value.slice) { - value = value.slice(byteOffset, byteOffset + byteLength); - } else { - // Android 4.1 does not have ArrayBuffer.prototype.slice - value = new Uint8Array(value); - if (value.byteLength !== byteLength) { - // TypedArray to ArrayBuffer to Uint8Array to Array - value = Array.prototype.slice.call(value, byteOffset, byteOffset + byteLength); - } - } - } - } else if (typeof value === "string") { - // String to Uint8Array - return Bufferish.from.call(exports, value); - } else if (typeof value === "number") { - throw new TypeError('"value" argument must not be a number'); - } - - return new Uint8Array(value); -} diff --git a/lib/bufferish.js b/lib/bufferish.js index d38d7c6..cdd20f6 100644 --- a/lib/bufferish.js +++ b/lib/bufferish.js @@ -1,6 +1,7 @@ // bufferish.js var Buffer = exports.global = require("./buffer-global"); +var BufferLite = require("./buffer-lite"); var hasBuffer = exports.hasBuffer = Buffer && !!Buffer.isBuffer; var hasArrayBuffer = exports.hasArrayBuffer = ("undefined" !== typeof ArrayBuffer); @@ -13,10 +14,15 @@ exports.alloc = alloc; exports.concat = concat; exports.from = from; -var BufferArray = exports.Array = require("./bufferish-array"); -var BufferBuffer = exports.Buffer = require("./bufferish-buffer"); -var BufferUint8Array = exports.Uint8Array = require("./bufferish-uint8array"); -var BufferProto = exports.prototype = require("./bufferish-proto"); +var BufferArray = exports.Array = allocArray(0); +var BufferBuffer = exports.Buffer = hasBuffer ? allocBuffer(0) : []; +var BufferUint8Array = exports.Uint8Array = hasArrayBuffer ? allocUint8Array(0) : []; +var BufferProto = exports.prototype = { + copy: copyProto, + slice: sliceProto, + toString: toStringProto, + write: genProto("write") +}; /** * @param value {Array|ArrayBuffer|Buffer|String} @@ -105,4 +111,199 @@ function _is(name, key) { return function(value) { return (value != null) && {}.toString.call(key ? value[key] : value) === name; }; -} \ No newline at end of file +} + +BufferArray.alloc = allocArray; +BufferArray.concat = concat; +BufferArray.from = fromArray; + +/** + * @param size {Number} + * @returns {Buffer|Uint8Array|Array} + */ + +function allocArray(size) { + return new Array(size); +} + +/** + * @param value {Array|ArrayBuffer|Buffer|String} + * @returns {Array} + */ + +function fromArray(value) { + if (!isBuffer(value) && isView(value)) { + // TypedArray to Uint8Array + value = BufferUint8Array.from(value); + } else if (isArrayBuffer(value)) { + // ArrayBuffer to Uint8Array + value = new Uint8Array(value); + } else if (typeof value === "string") { + // String to Array + return from.call(BufferArray, value); + } else if (typeof value === "number") { + throw new TypeError('"value" argument must not be a number'); + } + + // Array-like to Array + return Array.prototype.slice.call(value); +} + +BufferBuffer.alloc = hasBuffer && Buffer.alloc || allocBuffer; +BufferBuffer.concat = concat; +BufferBuffer.from = fromBuffer; + +/** + * @param size {Number} + * @returns {Buffer|Uint8Array|Array} + */ + +function allocBuffer(size) { + return new Buffer(size); +} + +/** + * @param value {Array|ArrayBuffer|Buffer|String} + * @returns {Buffer} + */ + +function fromBuffer(value) { + if (!isBuffer(value) && isView(value)) { + // TypedArray to Uint8Array + value = BufferUint8Array.from(value); + } else if (isArrayBuffer(value)) { + // ArrayBuffer to Uint8Array + value = new Uint8Array(value); + } else if (typeof value === "string") { + // String to Buffer + return from.call(BufferBuffer, value); + } else if (typeof value === "number") { + throw new TypeError('"value" argument must not be a number'); + } + + // Array-like to Buffer + if (Buffer.from && Buffer.from.length !== 1) { + return Buffer.from(value); // node v6+ + } else { + return new Buffer(value); // node v4 + } +} + +BufferUint8Array.alloc = allocUint8Array; +BufferUint8Array.concat = concat; +BufferUint8Array.from = fromUint8Array; + +/** + * @param size {Number} + * @returns {Buffer|Uint8Array|Array} + */ + +function allocUint8Array(size) { + return new Uint8Array(size); +} + +/** + * @param value {Array|ArrayBuffer|Buffer|String} + * @returns {Uint8Array} + */ + +function fromUint8Array(value) { + if (isView(value)) { + // TypedArray to ArrayBuffer + var byteOffset = value.byteOffset; + var byteLength = value.byteLength; + value = value.buffer; + if (value.byteLength !== byteLength) { + if (value.slice) { + value = value.slice(byteOffset, byteOffset + byteLength); + } else { + // Android 4.1 does not have ArrayBuffer.prototype.slice + value = new Uint8Array(value); + if (value.byteLength !== byteLength) { + // TypedArray to ArrayBuffer to Uint8Array to Array + value = Array.prototype.slice.call(value, byteOffset, byteOffset + byteLength); + } + } + } + } else if (typeof value === "string") { + // String to Uint8Array + return from.call(BufferUint8Array, value); + } else if (typeof value === "number") { + throw new TypeError('"value" argument must not be a number'); + } + + return new Uint8Array(value); +} + +var isBufferShim = hasBuffer && ("TYPED_ARRAY_SUPPORT" in Buffer); +var brokenTypedArray = isBufferShim && !Buffer.TYPED_ARRAY_SUPPORT; + +/** + * @param target {Buffer|Uint8Array|Array} + * @param [targetStart] {Number} + * @param [start] {Number} + * @param [end] {Number} + * @returns {Buffer|Uint8Array|Array} + */ + +function copyProto(target, targetStart, start, end) { + var thisIsBuffer = isBuffer(this); + var targetIsBuffer = isBuffer(target); + if (thisIsBuffer && targetIsBuffer) { + // Buffer to Buffer + return this.copy(target, targetStart, start, end); + } else if (!brokenTypedArray && !thisIsBuffer && !targetIsBuffer && + isView(this) && isView(target)) { + // Uint8Array to Uint8Array (except for minor some browsers) + var buffer = (start || end != null) ? sliceProto.call(this, start, end) : this; + target.set(buffer, targetStart); + return buffer.length; + } else { + // other cases + return BufferLite.copy.call(this, target, targetStart, start, end); + } +} + +/** + * @param [start] {Number} + * @param [end] {Number} + * @returns {Buffer|Uint8Array|Array} + */ + +function sliceProto(start, end) { + // for Buffer, Uint8Array (except for minor some browsers) and Array + var f = this.sliceProto || (!brokenTypedArray && this.subarray); + if (f) return f.call(this, start, end); + + // Uint8Array (for minor some browsers) + var target = alloc.call(this, end - start); + copyProto.call(this, target, 0, start, end); + return target; +} + +/** + * Buffer.prototype.toString() + * + * @param [encoding] {String} ignored + * @param [start] {Number} + * @param [end] {Number} + * @returns {String} + */ + +function toStringProto(encoding, start, end) { + var f = (!isBufferShim && isBuffer(this)) ? this.toString : BufferLite.toString; + return f.apply(this, arguments); +} + +/** + * @private + */ + +function genProto(method) { + return wrap; + + function wrap() { + var f = this[method] || BufferLite[method]; + return f.apply(this, arguments); + } +} diff --git a/lib/decode-buffer.js b/lib/decode-buffer.js index 56d8fae..425035e 100644 --- a/lib/decode-buffer.js +++ b/lib/decode-buffer.js @@ -1,27 +1,3 @@ // decode-buffer.js -exports.DecodeBuffer = DecodeBuffer; - -var preset = require("./read-core").preset; - -var FlexDecoder = require("./flex-buffer").FlexDecoder; - -FlexDecoder.mixin(DecodeBuffer.prototype); - -function DecodeBuffer(options) { - if (!(this instanceof DecodeBuffer)) return new DecodeBuffer(options); - - if (options) { - this.options = options; - if (options.codec) { - var codec = this.codec = options.codec; - if (codec.bufferish) this.bufferish = codec.bufferish; - } - } -} - -DecodeBuffer.prototype.codec = preset; - -DecodeBuffer.prototype.fetch = function() { - return this.codec.decode(this); -}; +exports.DecodeBuffer = require("./read-core").DecodeBuffer; diff --git a/lib/decode.js b/lib/decode.js index 75dbe1c..580a465 100644 --- a/lib/decode.js +++ b/lib/decode.js @@ -1,11 +1,3 @@ // decode.js -exports.decode = decode; - -var DecodeBuffer = require("./decode-buffer").DecodeBuffer; - -function decode(input, options) { - var decoder = new DecodeBuffer(options); - decoder.write(input); - return decoder.read(); -} \ No newline at end of file +exports.decode = require("./read-core").decode; \ No newline at end of file diff --git a/lib/encode-buffer.js b/lib/encode-buffer.js index 406d333..52b62b2 100644 --- a/lib/encode-buffer.js +++ b/lib/encode-buffer.js @@ -1,27 +1,3 @@ // encode-buffer.js -exports.EncodeBuffer = EncodeBuffer; - -var preset = require("./write-core").preset; - -var FlexEncoder = require("./flex-buffer").FlexEncoder; - -FlexEncoder.mixin(EncodeBuffer.prototype); - -function EncodeBuffer(options) { - if (!(this instanceof EncodeBuffer)) return new EncodeBuffer(options); - - if (options) { - this.options = options; - if (options.codec) { - var codec = this.codec = options.codec; - if (codec.bufferish) this.bufferish = codec.bufferish; - } - } -} - -EncodeBuffer.prototype.codec = preset; - -EncodeBuffer.prototype.write = function(input) { - this.codec.encode(this, input); -}; +exports.EncodeBuffer = require("./write-core").EncodeBuffer; diff --git a/lib/encode.js b/lib/encode.js index 30e688e..ef608d8 100644 --- a/lib/encode.js +++ b/lib/encode.js @@ -1,11 +1,3 @@ // encode.js -exports.encode = encode; - -var EncodeBuffer = require("./encode-buffer").EncodeBuffer; - -function encode(input, options) { - var encoder = new EncodeBuffer(options); - encoder.write(input); - return encoder.read(); -} +exports.encode = require("./write-core").encode; diff --git a/lib/ext-packer.js b/lib/ext-packer.js index 220a8bf..4a65af2 100644 --- a/lib/ext-packer.js +++ b/lib/ext-packer.js @@ -5,11 +5,10 @@ exports.setExtPackers = setExtPackers; var Bufferish = require("./bufferish"); var Buffer = Bufferish.global; var packTypedArray = Bufferish.Uint8Array.from; -var _encode; var ERROR_COLUMNS = {name: 1, message: 1, stack: 1, columnNumber: 1, fileName: 1, lineNumber: 1}; -function setExtPackers(codec) { +function setExtPackers(codec, encode) { codec.addExtPacker(0x0E, Error, [packError, encode]); codec.addExtPacker(0x01, EvalError, [packError, encode]); codec.addExtPacker(0x02, RangeError, [packError, encode]); @@ -52,11 +51,6 @@ function setExtPackers(codec) { } } -function encode(input) { - if (!_encode) _encode = require("./encode").encode; // lazy load - return _encode(input); -} - function packValueOf(value) { return (value).valueOf(); } diff --git a/lib/ext-unpacker.js b/lib/ext-unpacker.js index 03e525d..03fb231 100644 --- a/lib/ext-unpacker.js +++ b/lib/ext-unpacker.js @@ -4,11 +4,10 @@ exports.setExtUnpackers = setExtUnpackers; var Bufferish = require("./bufferish"); var Buffer = Bufferish.global; -var _decode; var ERROR_COLUMNS = {name: 1, message: 1, stack: 1, columnNumber: 1, fileName: 1, lineNumber: 1}; -function setExtUnpackers(codec) { +function setExtUnpackers(codec, decode) { codec.addExtUnpacker(0x0E, [decode, unpackError(Error)]); codec.addExtUnpacker(0x01, [decode, unpackError(EvalError)]); codec.addExtUnpacker(0x02, [decode, unpackError(RangeError)]); @@ -51,11 +50,6 @@ function setExtUnpackers(codec) { } } -function decode(input) { - if (!_decode) _decode = require("./decode").decode; // lazy load - return _decode(input); -} - function unpackRegExp(value) { return RegExp.apply(null, value); } diff --git a/lib/read-core.js b/lib/read-core.js index 3996fe3..abad046 100644 --- a/lib/read-core.js +++ b/lib/read-core.js @@ -5,6 +5,7 @@ var ExtUnpacker = require("./ext-unpacker"); var readUint8 = require("./read-format").readUint8; var ReadToken = require("./read-token"); var CodecBase = require("./codec-base"); +var FlexDecoder = require("./flex-buffer").FlexDecoder; CodecBase.install({ addExtUnpacker: addExtUnpacker, @@ -12,7 +13,8 @@ CodecBase.install({ init: init }); -exports.preset = init.call(CodecBase.preset); +var preset = init.call(CodecBase.preset); +exports.preset = preset; function getDecoder(options) { var readToken = ReadToken.getReadToken(options); @@ -31,7 +33,7 @@ function init() { this.decode = getDecoder(options); if (options && options.preset) { - ExtUnpacker.setExtUnpackers(this); + ExtUnpacker.setExtUnpackers(this, decode); } return this; @@ -50,3 +52,33 @@ function getExtUnpacker(type) { return new ExtBuffer(buffer, type); } } + +FlexDecoder.mixin(DecodeBuffer.prototype); + +function DecodeBuffer(options) { + if (!(this instanceof DecodeBuffer)) return new DecodeBuffer(options); + + if (options) { + this.options = options; + if (options.codec) { + var codec = this.codec = options.codec; + if (codec.bufferish) this.bufferish = codec.bufferish; + } + } +} + +DecodeBuffer.prototype.codec = preset; + +DecodeBuffer.prototype.fetch = function() { + return this.codec.decode(this); +}; + +exports.DecodeBuffer = DecodeBuffer; + +function decode(input, options) { + var decoder = new DecodeBuffer(options); + decoder.write(input); + return decoder.read(); +} + +exports.decode = decode; diff --git a/lib/read-format.js b/lib/read-format.js index c5a4975..d550c3a 100644 --- a/lib/read-format.js +++ b/lib/read-format.js @@ -9,7 +9,7 @@ exports.getReadFormat = getReadFormat; exports.readUint8 = uint8; var Bufferish = require("./bufferish"); -var BufferProto = require("./bufferish-proto"); +var BufferProto = Bufferish.prototype; var HAS_MAP = ("undefined" !== typeof Map); var NO_ASSERT = true; diff --git a/lib/write-core.js b/lib/write-core.js index 1fc0c14..efbaa0e 100644 --- a/lib/write-core.js +++ b/lib/write-core.js @@ -4,6 +4,7 @@ var ExtBuffer = require("./ext-buffer").ExtBuffer; var ExtPacker = require("./ext-packer"); var WriteType = require("./write-type"); var CodecBase = require("./codec-base"); +var FlexEncoder = require("./flex-buffer").FlexEncoder; CodecBase.install({ addExtPacker: addExtPacker, @@ -11,7 +12,8 @@ CodecBase.install({ init: init }); -exports.preset = init.call(CodecBase.preset); +var preset = init.call(CodecBase.preset); +exports.preset = preset; function getEncoder(options) { var writeType = WriteType.getWriteType(options); @@ -29,7 +31,7 @@ function init() { this.encode = getEncoder(options); if (options && options.preset) { - ExtPacker.setExtPackers(this); + ExtPacker.setExtPackers(this, encode); } return this; @@ -67,3 +69,33 @@ function getExtPacker(value) { if (c === pair[0]) return pair[1]; } } + +FlexEncoder.mixin(EncodeBuffer.prototype); + +function EncodeBuffer(options) { + if (!(this instanceof EncodeBuffer)) return new EncodeBuffer(options); + + if (options) { + this.options = options; + if (options.codec) { + var codec = this.codec = options.codec; + if (codec.bufferish) this.bufferish = codec.bufferish; + } + } +} + +EncodeBuffer.prototype.codec = preset; + +EncodeBuffer.prototype.write = function(input) { + this.codec.encode(this, input); +}; + +exports.EncodeBuffer = EncodeBuffer; + +function encode(input, options) { + var encoder = new EncodeBuffer(options); + encoder.write(input); + return encoder.read(); +} + +exports.encode = encode; diff --git a/lib/write-type.js b/lib/write-type.js index 94a10ab..f184c28 100644 --- a/lib/write-type.js +++ b/lib/write-type.js @@ -6,7 +6,7 @@ var Uint64BE = Int64Buffer.Uint64BE; var Int64BE = Int64Buffer.Int64BE; var Bufferish = require("./bufferish"); -var BufferProto = require("./bufferish-proto"); +var BufferProto = Bufferish.prototype; var WriteToken = require("./write-token"); var uint8 = require("./write-uint8").uint8; var ExtBuffer = require("./ext-buffer").ExtBuffer;