Home > Blockchain >  How do I convert from a byte array to different number types starting at arbitrary byte starts in ja
How do I convert from a byte array to different number types starting at arbitrary byte starts in ja

Time:10-14

I'm working with a file buffer and started processing it as a byte array:

//data is a buffer from reading my file
let view = new Uint8Array(data);

I want some function that will basically act like the DataView class, but that uses byte offsets, rather than offsets based on the converted type.

For example, let's say by byte array was [0 1 2 3 4 5 6] (sorry, not sure how to initialize this in code)

I'd like code something like this:

let int16_value = view.getUint16(1);

With the result being 513, or 1 256*2

I thought this might work, but the problem is it starts at the 2nd uint16 value, not at the 2nd byte

let view2 = new DataView(data);
let temp = view2.getUint16(1);

I'd like solutions for all different conversions (uint16,uint32,int16,single,double,etc.)

My impression is that this is not possible without just manually writing the conversions but I'm pretty new to javascript and wondering if there is some clever array slicing/copying solution where you could get something like this:

let temp = typecast(view,1,'uint16');

Where typecast takes in the byte array, the start (in bytes), and the data type to extract.

Bonus points if there is a nice solution that adds on number of elements to read with the default being 1 (as in above)

CodePudding user response:

the problem is it starts at the 2nd uint16 value.

No, the offset is in bytes.

You can declare an offset (also in bytes) at the construction of your DataView

new DataView(buffer, offset);

but calling getUint16(0) on this one will do the same as calling getUint16(1) on yours.

But from your expected result (513) it seems you expected LittleEndian to be the default. The default is actually BigEndian, and you need to pass true to the second argument of DataView.getUint16(offset, littleEndian).

// They all return the same value
const data = new Uint8Array([0, 1, 2, 3, 4, 5, 6]).buffer;

const fullView = new DataView(data);
console.log("offset @ get", fullView.getUint16(1, true));
const offsetView = new DataView(data, 1);
console.log("offset @ DataView", offsetView.getUint16(0, true));
// offset is made at the buffer level
// (just to show it's the same, don't actually do that)
const noOffsetData = new Uint8Array([1, 2, 3, 4, 5, 6]).buffer;
const noOffsetView = new DataView(noOffsetData);
console.log("offset @ buffer", noOffsetView.getUint16(0, true));

  • Related