diff options
author | Trevor Norris <trev.norris@gmail.com> | 2015-06-17 10:43:13 -0600 |
---|---|---|
committer | Rod Vagg <rod@vagg.org> | 2015-08-04 11:56:13 -0700 |
commit | 4643b8b6671607a7aff60cbbd0b384dcf2f6959e (patch) | |
tree | daad9f2689c4d1205b425f1674c7c0e21ff6b786 | |
parent | e5ada116cd59e7ab10c9e697736bdc5ea37e0ce9 (diff) | |
download | android-node-v8-4643b8b6671607a7aff60cbbd0b384dcf2f6959e.tar.gz android-node-v8-4643b8b6671607a7aff60cbbd0b384dcf2f6959e.tar.bz2 android-node-v8-4643b8b6671607a7aff60cbbd0b384dcf2f6959e.zip |
buffer: allow ArrayBuffer as Buffer argument
Buffer now uses the ArrayBuffer as the backing store if passed to the
constructor.
Fixes: https://github.com/nodejs/io.js/issues/106
PR-URL: https://github.com/nodejs/io.js/pull/2002
Reviewed-By: Domenic Denicola <d@domenic.me>
-rw-r--r-- | lib/internal/buffer_new.js | 5 | ||||
-rw-r--r-- | src/node_buffer.cc | 15 | ||||
-rw-r--r-- | test/parallel/test-buffer-arraybuffer.js | 46 |
3 files changed, 65 insertions, 1 deletions
diff --git a/lib/internal/buffer_new.js b/lib/internal/buffer_new.js index 3b3a200614..8a30fc5c3a 100644 --- a/lib/internal/buffer_new.js +++ b/lib/internal/buffer_new.js @@ -104,7 +104,10 @@ function fromObject(obj) { return b; } - // TODO(trevnorris): This will fail for an actual ArrayBuffer. + if (obj instanceof ArrayBuffer) { + return binding.createFromArrayBuffer(obj); + } + if (obj.buffer instanceof ArrayBuffer || obj.length) { var length; if (typeof obj.length !== 'number' || obj.length !== obj.length) diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 96cd61f89e..dbd1489019 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -528,6 +528,20 @@ void CreateFromString(const FunctionCallbackInfo<Value>& args) { } +void CreateFromArrayBuffer(const FunctionCallbackInfo<Value>& args) { + Environment* env = Environment::GetCurrent(args); + if (!args[0]->IsArrayBuffer()) + return env->ThrowTypeError("argument is not an ArrayBuffer"); + Local<ArrayBuffer> ab = args[0].As<ArrayBuffer>(); + Local<Uint8Array> ui = Uint8Array::New(ab, 0, ab->ByteLength()); + Maybe<bool> mb = + ui->SetPrototype(env->context(), env->buffer_prototype_object()); + if (!mb.FromMaybe(false)) + return env->ThrowError("Unable to set Object prototype"); + args.GetReturnValue().Set(ui); +} + + void Slice(const FunctionCallbackInfo<Value>& args) { CHECK(args[0]->IsUint8Array()); CHECK(args[1]->IsNumber()); @@ -1171,6 +1185,7 @@ void Initialize(Handle<Object> target, env->SetMethod(target, "setupBufferJS", SetupBufferJS); env->SetMethod(target, "create", Create); env->SetMethod(target, "createFromString", CreateFromString); + env->SetMethod(target, "createFromArrayBuffer", CreateFromArrayBuffer); env->SetMethod(target, "slice", Slice); env->SetMethod(target, "byteLengthUtf8", ByteLengthUtf8); diff --git a/test/parallel/test-buffer-arraybuffer.js b/test/parallel/test-buffer-arraybuffer.js new file mode 100644 index 0000000000..c13d0ba411 --- /dev/null +++ b/test/parallel/test-buffer-arraybuffer.js @@ -0,0 +1,46 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +const Buffer = require('buffer').Buffer; +const LENGTH = 16; + +const ab = new ArrayBuffer(LENGTH); +const dv = new DataView(ab); +const ui = new Uint8Array(ab); +const buf = new Buffer(ab); + + +assert.ok(buf instanceof Buffer); +// For backwards compatibility of old .parent property test that if buf is not +// a slice then .parent should be undefined. +assert.equal(buf.parent, undefined); +assert.equal(buf.buffer, ab); +assert.equal(buf.length, ab.byteLength); + + +buf.fill(0xC); +for (let i = 0; i < LENGTH; i++) { + assert.equal(ui[i], 0xC); + ui[i] = 0xF; + assert.equal(buf[i], 0xF); +} + +buf.writeUInt32LE(0xF00, 0); +buf.writeUInt32BE(0xB47, 4); +buf.writeDoubleLE(3.1415, 8); + +assert.equal(dv.getUint32(0, true), 0xF00); +assert.equal(dv.getUint32(4), 0xB47); +assert.equal(dv.getFloat64(8, true), 3.1415); + + +// Now test protecting users from doing stupid things + +assert.throws(function() { + function AB() { } + AB.__proto__ = ArrayBuffer; + AB.prototype.__proto__ = ArrayBuffer.prototype; + new Buffer(new AB()); +}, TypeError); |