Search code examples
javascriptendiannessbinary-data

Why endianness mismatch happens in this code?


Here is simple piece of code from this fiddle: https://jsfiddle.net/vo0aL8h4/2/ It is about a binary endianness issue while making a cross-browser binary data reader/writer code.

I was wrong here as well

That 0x00000101 is 257 in decimal, it was saved to a binary file as Uint32. Is it little endian representation, yes?

It is very strange that it is being read incorrectly by DataView.getUint32 . So I created a fiddle to check in browser an issue I experienced in Node.


let data = new Uint8Array([0,0,1,1]);
let view = new DataView(data.buffer);
writeLog(`reading little endian data (${data.join()}):  ${view.getUint32(0, true)}`);
writeLog(`reading big endian data (${data.join()}):  ${view.getUint32(0, false)}`);

Output:

reading little endian data (0,0,1,1): 16842752
reading big endian data (0,0,1,1): 257

What I missing? Is that DataView.getUint32 vs setUint32 work differently about

Update

Thanks for your comments and answer. it inspired me to re-check whether the endianness flag applied properly.

This code was a bug:

    constructor(littleEndian?:boolean) {
        if (littleEndian === undefined) {
            this.#littleEndian = isMachineLittleEndian;
        }
    }

and it was incorrect implementation, it was missing branch.

Correct version:

    constructor(littleEndian?:boolean) {
        if (littleEndian === undefined) {
            this.#littleEndian = isMachineLittleEndian;
        } else {
            this.#littleEndian = !!littleEndian;
        }
    }

Hope this question and answers will help someone as an example of what happens if you provide somewhere undefined to setUint32 and later set a true value in getUint32.


Solution

  • That 0x00000101 is 257 in decimal, it was saved to a binary file as Uint32. Is it little endian representation, yes?

    No, that's big-endian, because the most-significant byte is first.

    You need to do this:

    let data = new Uint8Array([0,0,1,1]);
    let view = new DataView(data.buffer);
    console.log(view.getUint32(0, false)); // prints 257