Rafał Łużyński
Rafał Łużyński

Reputation: 7312

Converting value to bytearray in javascript

I'm writing app based on WebSocket networking using binary frames. I want to send values from Python server to JS client and back.

From what I know, values packed in more then 8-bits depends on endian when unpacking and packing. Unfortunately browser seems to be sending everything in little-endian and network is big-endian. So I read that the best idea is to pack all values into byte arrays so endian won't matter.

I wrote this function for javascript:

valueToByteArray: function(value, bytes_length) {
    var bytes_array = [];
    for (var i=bytes_length - 1; i>=0; --i) {
        conjunction_val = 0xFF << i*8;
        shift = i*8;
        bytes_array.push((value & conjunction_val) >> shift);
    }
    return bytes_array;
}

And I have tests for it:

test("Pack value to Byte array", function() {
    equal(
        BufferUtility.valueToByteArray(-2000000, 4),
        [255, 225, 123, 128],
        "Value packed OK"
    ); // fail returns [-1, 225, 123, 128], same function in python returns [255L, 225, 123, 128]
    equal(
        BufferUtility.valueToByteArray(4000000, 4),
        [0, 61, 9, 0],
        "Value packed OK"
    ); // pass
    equal(
        BufferUtility.valueToByteArray(0, 2),
        [0, 0],
        "Value packed OK"
    ); // pass
    equal(
        BufferUtility.valueToByteArray(-1, 2),
        [128, 1],
        "Value packed OK"
    ); // fail returns [255, 255]
});

But only second and third test pass, it seems to not work for signed values. I also checked this values on Python, and it looks like struct.pack('>h', -1) is \xFF\xFF. I don't understand it honestly. Since MSb is a sign bit, then shortint -1 binary should be imo 1000000000000001.

What am I doing wrong and maybe is there a better way to fix issues with endian?

Upvotes: 2

Views: 1152

Answers (1)

Rafał Łużyński
Rafał Łużyński

Reputation: 7312

I got this code from #javascript on Freenode an it suprisingly works, even that it does exactly the same thing in different way :|

function valueToByteArray(value, bytes_length) {
    var bytes_array = [];
    while (bytes_length > 0){
        var byte = value & 0xFF;
        value >>= 8;
        bytes_length--;

        bytes_array.push(byte);
    }
    return bytes_array.reverse();
}

console.log(valueToByteArray(-2000000, 4));
<< [255, 225, 123, 128]

Upvotes: 1

Related Questions