Right way to access ArrayBufferView and ArrayBuffer.

781 views
Skip to first unread message

Elia Mazzuoli

unread,
Jul 4, 2016, 6:00:08 AM7/4/16
to v8-users
Hi all, I'm trying to access data inside an ArrayBufferView. This is my simple javascript code:

const myAddon = require('addon location');

const myObj = myAddon.MyObj();

const data = Buffer.from('test');
myObj
= doSomething(data);

After that in my c++ I have this:

void MyObj::doSomething(const v8::FunctionCallbackInfo<v8::Value> &args) {) {

    Local<v8::ArrayBufferView> dataBufferView = Local<v8::ArrayBufferView>::Cast(args[1]);
    std::cout << "Lenght on dataBufferView: " << dataBufferView->ByteLength() << std::endl;
    std::cout << "Byte offset on dataBufferView: " << dataBufferView->ByteOffset() << std::endl;
         
     
Local
<ArrayBuffer> dataBuffer = dataBufferView->Buffer();
     std::cout << "Lenght dataBuffer: " << dataBuffer->ByteLength() << std::endl;
     ArrayBuffer::Contents dataContent = dataBuffer->Externalize();

     uint8_t* startData = static_cast<uint8_t*>(dataContent.Data());
     std::cout << "Content of " <<dataContent.ByteLength() << " from js: ";
     for(unsigned int i = 0; i < dataContent->ByteLength(); i++) {
        std::cout << *(startData + i);
     }
     std::cout << std::endl;

}

What is strange in this simple code is that dataBuffer->ByteLength() is 8192 and if I print out the data content what I see is my full javascript code and some other binary data.

So.. what is the right way to access data?

Ben Noordhuis

unread,
Jul 4, 2016, 6:06:43 AM7/4/16
to v8-users
node::Buffer::Data() and node::Buffer::Length() from node_buffer.h.

Using v8::ArrayBufferView won't work in node.js versions where Buffer
is not an instance of Uint8Array.

Elia Mazzuoli

unread,
Jul 4, 2016, 8:24:23 AM7/4/16
to v8-users
Umm thank you for the response... but isn't clear for me. Now I develop on version 6.2.1 seems that "ArrayBufferView" have an instance of Uint8Array.. but how this help for my questions?

1. Why I see inside my "ArrayBuffer" the entire js code and other binary content?
2. What is the right way for access to data?

Ben Noordhuis

unread,
Jul 4, 2016, 9:16:34 AM7/4/16
to v8-users
On Mon, Jul 4, 2016 at 2:24 PM, Elia Mazzuoli <zik...@gmail.com> wrote:
> Umm thank you for the response... but isn't clear for me. Now I develop on
> version 6.2.1 seems that "ArrayBufferView" have an instance of Uint8Array..
> but how this help for my questions?
>
> 1. Why I see inside my "ArrayBuffer" the entire js code and other binary
> content?

Buffers can be sliced off a larger buffer. The ArrayBuffer is that
larger buffer.

> 2. What is the right way for access to data?

I already told you.

Zach Bjornson

unread,
Sep 2, 2016, 12:14:27 AM9/2/16
to v8-users
Not sure if you still need help with this, but ... expanding on what Ben said:

Node Buffers are Uint8Arrays (ArrayBufferViews) in version 4.x and later only.

Small node Buffers ([currently] <4096 bytes) use a shared buffer as a backing store, which is why you see a greater byteLength. You need to observe the byteOffset and byteLength to find the section of the shared buffer that belongs to your buffer.

If you want something for Buffers compatible going back to node 0.10, use Buffer::Data() from node_buffer.h, which takes care of the byteOffset for you:

char* Data(Local<Value> val) {
  CHECK
(val->IsUint8Array());
 
Local<Uint8Array> ui = val.As<Uint8Array>();
 
ArrayBuffer::Contents ab_c = ui->Buffer()->GetContents();
 
return static_cast<char*>(ab_c.Data()) + ui->ByteOffset();
}

If you really want to handle them as Uint8Arrays, there's an example using nan (native abstractions for node) to access typed array contents here:
And an example without the nan macro here:
But using node's exported function should be preferable if you're actually consuming Buffers.

-Zach
Reply all
Reply to author
Forward
0 new messages