summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrevor Norris <trev.norris@gmail.com>2013-05-15 11:01:33 -0700
committerTrevor Norris <trev.norris@gmail.com>2013-06-18 15:39:32 -0700
commitfb40da822fa8bb6da588af1989aaf32ef01d0a17 (patch)
treee039eceebaff60372da7b89d3e4846898e691be1
parent456942a920fe313ebe0b0da366d26ef400ec177e (diff)
downloadnode-fb40da822fa8bb6da588af1989aaf32ef01d0a17.tar.gz
buffer: expose class methods alloc and dispose
Expose the ability for users to allocate and manually dispose data on any object. These are user-safe versions of internal smalloc functions.
-rw-r--r--doc/api/buffer.markdown40
-rw-r--r--lib/buffer.js20
-rw-r--r--test/simple/test-buffer.js37
3 files changed, 97 insertions, 0 deletions
diff --git a/doc/api/buffer.markdown b/doc/api/buffer.markdown
index d880911f0..3ddd41320 100644
--- a/doc/api/buffer.markdown
+++ b/doc/api/buffer.markdown
@@ -126,6 +126,46 @@ If totalLength is not provided, it is read from the buffers in the list.
However, this adds an additional loop to the function, so it is faster
to provide the length explicitly.
+### Class Method: Buffer.alloc(length, [receiver])
+
+* `length` Number
+* `receiver` Object, Optional, Default: `new Object`
+
+
+**(EXPERIMENTAL)** Returns object with allocated external array data.
+
+Buffers are backed by a simple allocator that only handles the assignation of
+external raw memory. This exposes that functionality.
+
+No pooling is performed for these allocations. So there's no form of memory
+leak.
+
+This can be used to create your own Buffer-like classes.
+
+ function SimpleData(n) {
+ this.length = n;
+ Buffer.alloc(this.length, this);
+ }
+
+ SimpleData.prototype = { /* ... */ };
+
+### Class Method: Buffer.dispose(obj)
+
+* `obj` Object
+
+
+**(EXPERIMENTAL)** Free memory that has been allocated to an object via
+`Buffer.alloc`.
+
+ var a = {};
+ Buffer.alloc(3, a);
+
+ // { '0': 0, '1': 0, '2': 0 }
+
+ Buffer.dispose(a);
+
+ // {}
+
### buf.length
* Number
diff --git a/lib/buffer.js b/lib/buffer.js
index e0ce4c545..a21fb79f2 100644
--- a/lib/buffer.js
+++ b/lib/buffer.js
@@ -176,6 +176,26 @@ Buffer.concat = function(list, length) {
};
+Buffer.alloc = function(n, obj) {
+ n = ~~n;
+ if (n < 0) n = 0;
+
+ if (n > kMaxLength)
+ throw new RangeError('n > kMaxLength');
+ if (Array.isArray(obj))
+ throw new TypeError('Arrays are not supported');
+
+ return alloc(obj != null ? obj : {}, n);
+};
+
+
+Buffer.dispose = function(obj) {
+ if (obj instanceof Buffer)
+ throw new TypeError('obj cannot be a Buffer');
+ smalloc.dispose(obj);
+};
+
+
// toString(encoding, start=0, end=buffer.length)
Buffer.prototype.toString = function(encoding, start, end) {
encoding = !!encoding ? (encoding + '').toLowerCase() : 'utf8';
diff --git a/test/simple/test-buffer.js b/test/simple/test-buffer.js
index b5a76d90f..19fa4eacb 100644
--- a/test/simple/test-buffer.js
+++ b/test/simple/test-buffer.js
@@ -923,3 +923,40 @@ assert.equal(Buffer.byteLength('aaaa==', 'base64'), 3);
assert.throws(function() {
Buffer('', 'buffer');
}, TypeError);
+
+
+// test Buffer alloc
+
+// arrays are unsupported by v8
+assert.throws(function() {
+ Buffer.alloc(0, []);
+}, TypeError);
+
+// can't create too large an alloc
+assert.throws(function() {
+ Buffer.alloc(0x3fffffff + 1);
+}, RangeError);
+
+// make sure values are assigned
+var b = {};
+Buffer.alloc(256, b);
+for (var i = 0; i < 256; i++)
+ b[i] = i;
+for (var i = 0; i < 256; i++)
+ assert.equal(b[i], i);
+assert.equal(b[257], undefined);
+
+// several other types that shouldn't throw
+Buffer.alloc(1, function() { });
+Buffer.alloc(1, /abc/);
+Buffer.alloc(1, new Date());
+
+
+// make sure disposal works
+var b = {};
+Buffer.alloc(5, b);
+for (var i = 0; i < 5; i++)
+ b[i] = i;
+Buffer.dispose(b);
+for (var i = 0; i < 5; i++)
+ assert.equal(b[i], undefined);