Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Writing Int32 to ByteBuffer yields strange result in DataView #55

Open
tfalencar opened this issue Jul 29, 2015 · 2 comments
Open

Writing Int32 to ByteBuffer yields strange result in DataView #55

tfalencar opened this issue Jul 29, 2015 · 2 comments

Comments

@tfalencar
Copy link

Hello,

I'm not familiar with ByteBuffer (trying it for the first time due protobuf.js), but I'm trying to simply write an int32 to the buffer, convert it to a ArrayBuffers and see this value in 4 bytes in a file output. I'm pretty sure I'm doing some nasty mistake and it's not the library's fault, but this is one of the ways I've tried:

var ByteBuffer = dcodeIO.ByteBuffer;
//below is run inside a loop
var byteBuffer = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN);
byteBuffer.append(new ByteBuffer().writeInt32(data.calculate()));

//finally, generate the file for download
var data = new Blob([new DataView(byteBuffer.toArrayBuffer())], {type: 'application/octet-stream'});
this.url = ($window.URL || $window.webkitURL).createObjectURL(data);

then in html there's a field to download the file, as in:

<a download="vat.scope" ng-href="{{ vatEditor.url }}">download</a>

For example, when data.calculate() yields 32, I'd expect to see 0x 20 00 00 00, but what I got is 0x 28 00 38 05 (which in little endian integer is 87556136). Anyone would be kind to help me pinpoint the mistake(s) here?

A more extensive explanation of what I'm trying to accomplish can be found here.

@dcodeIO
Copy link
Member

dcodeIO commented Jul 29, 2015

Make sure to call flip() once all relative write operations are complete. See: https://github.com/dcodeIO/ByteBuffer.js/wiki/Offset-and-limit

var bb = new ByteBuffer().LE();
for (...) {
  // bb.append(new ByteBuffer().LE().writeInt32(data.calculate()).flip());
  bb.writeInt32(data.calculate());
}
var ab = bb.flip().toArrayBuffer();
...

@tfalencar
Copy link
Author

HOORAY! it works now! I actually tried the short version as well before, but it didn't come to me that when using .toArrayBuffer() that is effectively performing a read operation, and per docs if I understood it right when switching from read/write operations a flip() is necessary, so that explains it (I forgot to add it when creating the DataView() after using .toArrayBuffer().

Just for clarity writing both mentioned ways works now:

byteBuffer.writeInt32(data.calculate());
//or
byteBuffer.append(new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN).writeInt32(data.calculate()).flip());

//the important, forgotten flip() - 'implicit' read operation:
new Blob([new DataView(byteBuffer.flip().toArrayBuffer())]

Thanks a lot !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants