diff options
author | Tim-Smart <tim@fostle.com> | 2010-08-21 18:28:00 +1200 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2010-09-09 11:03:47 -0700 |
commit | 746d487da86048d09574cd40c6a76bc489d19ca9 (patch) | |
tree | 50044073fa1565d91974d0fb0705f1029476bc4d /lib/buffer.js | |
parent | ef54777fa5982da85dfb5e8ec4f2eaa36714e344 (diff) | |
download | node-746d487da86048d09574cd40c6a76bc489d19ca9.tar.gz |
FastBuffer implementation. API needs migration
Diffstat (limited to 'lib/buffer.js')
-rw-r--r-- | lib/buffer.js | 165 |
1 files changed, 163 insertions, 2 deletions
diff --git a/lib/buffer.js b/lib/buffer.js index 85c0bfece..3514359c7 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -1,7 +1,5 @@ var Buffer = process.binding('buffer').Buffer; -exports.Buffer = Buffer; - function toHex (n) { if (n < 16) return "0" + n.toString(16); return n.toString(16); @@ -87,3 +85,166 @@ Buffer.prototype.get = function (index) { Buffer.prototype.set = function (index, value) { return this[index] = value; }; + +// FastBuffer +var POOLSIZE = 8*1024; +var pool; + +function allocPool () { + pool = new Buffer(POOLSIZE); + pool.used = 0; +} + +function FastBuffer (subject, encoding, legacy, slice_legacy) { + var length, type; + + // Are we slicing? + if (typeof legacy === 'number') { + this.parent = subject; + this.length = encoding; + this.offset = legacy; + legacy = slice_legacy; + } else { + // Find the length + switch (type = typeof subject) { + case 'number': + length = subject; + break; + + case 'string': + case 'object': // Assume object is an array + length = subject.length; + break; + + default: + throw new Error("First argument need to be an number, array or string."); + } + + this.length = length; + + if (length > POOLSIZE) { + // Big buffer, just alloc one. + this.parent = new Buffer(subject, encoding); + this.offset = 0; + } else { + // Small buffer. + if (!pool || pool.length - pool.used < length) allocPool(); + this.parent = pool; + this.offset = pool.used; + pool.used += length; + + // Do we need to write stuff? + if (type !== 'number') { + // Assume object is an array + if (type === 'object') { + for (var i = 0; i < length; i++) { + this.parent[i + this.offset] = subject[i]; + } + } else { + // We are a string + this.write(subject, 0, encoding); + } + } + } + } + + // Make sure the api is equivilent to old buffers, unless user doesn't + // want overhead + if (legacy !== false) { + Buffer.makeFastBuffer(this.parent, this, this.offset, this.length); + } +} + +exports.FastBuffer = FastBuffer; +exports.Buffer = FastBuffer; + +// Static methods +FastBuffer.isBuffer = function isBuffer(b) { + return b instanceof FastBuffer; +}; + +// Inspect +FastBuffer.prototype.inspect = function inspect() { + var out = [], + len = this.length; + for (var i = 0; i < len; i++) { + out[i] = toHex(this.parent[i + this.offset]); + } + return "<Buffer " + out.join(" ") + ">"; +}; + +FastBuffer.prototype.get = function (i) { + if (i < 0 || i >= this.length) throw new Error("oob"); + return this.parent[this.offset + i]; +}; + +FastBuffer.prototype.set = function (i, v) { + if (i < 0 || i >= this.length) throw new Error("oob"); + return this.parent[this.offset + i] = v; +}; + +// TODO define slice, toString, write, etc. +// slice should not use c++ + +// write(string, offset = 0, encoding = 'uft8') +FastBuffer.prototype.write = function write (string, offset, encoding) { + if (!isFinite(offset)) { + var swap = encoding; + encoding = offset; + offset = swap; + } + + var max_length; + offset || (offset = 0); + encoding || (encoding = 'uft8'); + + // Make sure we are not going to overflow + max_length = this.length - offset; + if (string.length > max_length) { + string = string.slice(0, max_length); + } + + return this.parent.write(string, this.offset + offset, encoding); +} + +// toString(encoding, start=0, end=buffer.length) +FastBuffer.prototype.toString = function toSting (encoding, start, end) { + encoding || (encoding = 'utf8'); + start || (start = 0); + end || (end = this.length); + + // Make sure we aren't oob + if (end > this.length) { + end = this.length; + } + + return this.parent.toString(encoding, start + this.offset, end + this.offset); +}; + +// byteLength +FastBuffer.byteLength = Buffer.byteLength; + +// copy(targetBuffer, targetStart, sourceStart, sourceEnd=buffer.length) +FastBuffer.prototype.copy = function copy (target_buffer, target_start, start, end) { + start || (start = 0); + end || (end = this.length); + + // Are we oob? + if (end > this.length) { + end = this.length; + } + + return this.parent.copy(target_buffer, target_start, start + this.offset, end + this.offset); +}; + +// slice(start, end) +FastBuffer.prototype.slice = function slice (start, end, legacy) { + if (end > this.length) { + throw new Error("oob"); + } + if (start > end) { + throw new Error("oob"); + } + + return new FastBuffer(this.parent, end - start, +start + this.offset, legacy); +}; |