2010-08-21 19:18:15 +08:00
|
|
|
var SlowBuffer = process.binding('buffer').Buffer;
|
2010-03-20 11:50:29 +08:00
|
|
|
|
2010-03-26 00:50:49 +08:00
|
|
|
function toHex (n) {
|
|
|
|
if (n < 16) return "0" + n.toString(16);
|
|
|
|
return n.toString(16);
|
|
|
|
}
|
|
|
|
|
2010-08-21 19:18:15 +08:00
|
|
|
SlowBuffer.isSlowBuffer = function (b) {
|
|
|
|
return b instanceof SlowBuffer;
|
2010-07-16 05:37:03 +08:00
|
|
|
};
|
|
|
|
|
2010-08-21 19:18:15 +08:00
|
|
|
SlowBuffer.prototype.inspect = function () {
|
2010-07-22 19:51:26 +08:00
|
|
|
var out = [],
|
|
|
|
len = this.length;
|
|
|
|
for (var i = 0; i < len; i++) {
|
|
|
|
out[i] = toHex(this[i]);
|
2010-03-26 00:50:49 +08:00
|
|
|
}
|
2010-08-21 19:18:15 +08:00
|
|
|
return "<SlowBuffer " + out.join(" ") + ">";
|
2010-03-20 11:50:29 +08:00
|
|
|
};
|
|
|
|
|
2010-08-21 19:18:15 +08:00
|
|
|
SlowBuffer.prototype.toString = function (encoding, start, stop) {
|
2010-07-22 19:51:26 +08:00
|
|
|
encoding = String(encoding || 'utf8').toLowerCase();
|
|
|
|
start = +start || 0;
|
|
|
|
if (typeof stop == "undefined") stop = this.length;
|
2010-07-21 06:23:30 +08:00
|
|
|
|
|
|
|
// Fastpath empty strings
|
2010-07-22 19:51:26 +08:00
|
|
|
if (+stop == start) {
|
2010-07-21 06:23:30 +08:00
|
|
|
return '';
|
|
|
|
}
|
2010-03-26 23:35:46 +08:00
|
|
|
|
2010-04-09 07:31:02 +08:00
|
|
|
switch (encoding) {
|
|
|
|
case 'utf8':
|
|
|
|
case 'utf-8':
|
|
|
|
return this.utf8Slice(start, stop);
|
|
|
|
|
|
|
|
case 'ascii':
|
|
|
|
return this.asciiSlice(start, stop);
|
|
|
|
|
|
|
|
case 'binary':
|
|
|
|
return this.binarySlice(start, stop);
|
|
|
|
|
2010-07-24 04:52:44 +08:00
|
|
|
case 'base64':
|
|
|
|
return this.base64Slice(start, stop);
|
|
|
|
|
2010-04-09 07:31:02 +08:00
|
|
|
default:
|
|
|
|
throw new Error('Unknown encoding');
|
2010-03-26 23:35:46 +08:00
|
|
|
}
|
2010-03-20 11:50:29 +08:00
|
|
|
};
|
|
|
|
|
2010-08-21 19:18:15 +08:00
|
|
|
SlowBuffer.prototype.write = function (string, offset, encoding) {
|
2010-06-30 10:10:39 +08:00
|
|
|
// Support both (string, offset, encoding)
|
|
|
|
// and the legacy (string, encoding, offset)
|
2010-07-22 19:51:26 +08:00
|
|
|
if (!isFinite(offset)) {
|
|
|
|
var swap = encoding;
|
|
|
|
encoding = offset;
|
|
|
|
offset = swap;
|
2010-06-30 10:10:39 +08:00
|
|
|
}
|
|
|
|
|
2010-07-22 19:51:26 +08:00
|
|
|
offset = +offset || 0;
|
|
|
|
encoding = String(encoding || 'utf8').toLowerCase();
|
2010-06-30 10:10:39 +08:00
|
|
|
|
2010-04-09 07:31:02 +08:00
|
|
|
switch (encoding) {
|
|
|
|
case 'utf8':
|
|
|
|
case 'utf-8':
|
|
|
|
return this.utf8Write(string, offset);
|
|
|
|
|
|
|
|
case 'ascii':
|
|
|
|
return this.asciiWrite(string, offset);
|
|
|
|
|
|
|
|
case 'binary':
|
|
|
|
return this.binaryWrite(string, offset);
|
|
|
|
|
2010-07-24 07:36:47 +08:00
|
|
|
case 'base64':
|
|
|
|
return this.base64Write(string, offset);
|
|
|
|
|
2010-04-09 07:31:02 +08:00
|
|
|
default:
|
|
|
|
throw new Error('Unknown encoding');
|
|
|
|
}
|
2010-08-20 14:29:06 +08:00
|
|
|
};
|
|
|
|
|
2010-08-21 19:18:15 +08:00
|
|
|
SlowBuffer.prototype.get = function (index) {
|
2010-08-20 14:29:06 +08:00
|
|
|
return this[index];
|
|
|
|
};
|
|
|
|
|
2010-08-21 19:18:15 +08:00
|
|
|
SlowBuffer.prototype.set = function (index, value) {
|
2010-08-20 14:29:06 +08:00
|
|
|
return this[index] = value;
|
|
|
|
};
|
2010-08-21 14:28:00 +08:00
|
|
|
|
2010-08-21 19:18:15 +08:00
|
|
|
// Buffer
|
2010-08-21 14:28:00 +08:00
|
|
|
var POOLSIZE = 8*1024;
|
|
|
|
var pool;
|
|
|
|
|
|
|
|
function allocPool () {
|
2010-08-21 19:18:15 +08:00
|
|
|
pool = new SlowBuffer(POOLSIZE);
|
2010-08-21 14:28:00 +08:00
|
|
|
pool.used = 0;
|
|
|
|
}
|
|
|
|
|
2010-08-21 19:18:15 +08:00
|
|
|
function Buffer (subject, encoding, legacy, slice_legacy) {
|
2010-08-21 14:28:00 +08:00
|
|
|
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.
|
2010-08-21 19:18:15 +08:00
|
|
|
this.parent = new SlowBuffer(subject, encoding);
|
2010-08-21 14:28:00 +08:00
|
|
|
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) {
|
2010-08-21 19:18:15 +08:00
|
|
|
SlowBuffer.makeFastBuffer(this.parent, this, this.offset, this.length);
|
2010-08-21 14:28:00 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-21 19:18:15 +08:00
|
|
|
exports.Buffer = Buffer;
|
2010-08-21 14:28:00 +08:00
|
|
|
|
|
|
|
// Static methods
|
2010-08-21 19:18:15 +08:00
|
|
|
Buffer.isBuffer = function isBuffer(b) {
|
|
|
|
return b instanceof Buffer;
|
2010-08-21 14:28:00 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
// Inspect
|
2010-08-21 19:18:15 +08:00
|
|
|
Buffer.prototype.inspect = function inspect() {
|
2010-08-21 14:28:00 +08:00
|
|
|
var out = [],
|
|
|
|
len = this.length;
|
|
|
|
for (var i = 0; i < len; i++) {
|
|
|
|
out[i] = toHex(this.parent[i + this.offset]);
|
|
|
|
}
|
|
|
|
return "<Buffer " + out.join(" ") + ">";
|
|
|
|
};
|
|
|
|
|
2010-08-21 19:18:15 +08:00
|
|
|
Buffer.prototype.get = function get (i) {
|
2010-08-21 14:28:00 +08:00
|
|
|
if (i < 0 || i >= this.length) throw new Error("oob");
|
|
|
|
return this.parent[this.offset + i];
|
|
|
|
};
|
|
|
|
|
2010-08-21 19:18:15 +08:00
|
|
|
Buffer.prototype.set = function set (i, v) {
|
2010-08-21 14:28:00 +08:00
|
|
|
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')
|
2010-08-21 19:18:15 +08:00
|
|
|
Buffer.prototype.write = function write (string, offset, encoding) {
|
2010-08-21 14:28:00 +08:00
|
|
|
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)
|
2010-08-21 19:18:15 +08:00
|
|
|
Buffer.prototype.toString = function toString (encoding, start, end) {
|
2010-08-21 14:28:00 +08:00
|
|
|
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
|
2010-08-21 19:18:15 +08:00
|
|
|
Buffer.byteLength = SlowBuffer.byteLength;
|
2010-08-21 14:28:00 +08:00
|
|
|
|
|
|
|
// copy(targetBuffer, targetStart, sourceStart, sourceEnd=buffer.length)
|
2010-08-21 19:18:15 +08:00
|
|
|
Buffer.prototype.copy = function copy (target, target_start, start, end) {
|
2010-08-21 14:28:00 +08:00
|
|
|
start || (start = 0);
|
|
|
|
end || (end = this.length);
|
|
|
|
|
|
|
|
// Are we oob?
|
|
|
|
if (end > this.length) {
|
|
|
|
end = this.length;
|
|
|
|
}
|
|
|
|
|
2010-08-21 19:18:15 +08:00
|
|
|
return this.parent.copy(target.parent, target_start + target.offset, start + this.offset, end + this.offset);
|
2010-08-21 14:28:00 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
// slice(start, end)
|
2010-08-21 19:18:15 +08:00
|
|
|
Buffer.prototype.slice = function slice (start, end, legacy) {
|
2010-08-21 14:28:00 +08:00
|
|
|
if (end > this.length) {
|
|
|
|
throw new Error("oob");
|
|
|
|
}
|
|
|
|
if (start > end) {
|
|
|
|
throw new Error("oob");
|
|
|
|
}
|
|
|
|
|
2010-08-21 19:18:15 +08:00
|
|
|
return new Buffer(this.parent, end - start, +start + this.offset, legacy);
|
2010-08-21 14:28:00 +08:00
|
|
|
};
|