Search code examples
javascriptarrayswebsocketbinarytyped-arrays

Merging typed arrays of different data type into a single arraybuffer


I'd like to know if there's a way of merging multiple typed arrays of different types into one arraybuffer.

At the moment I'm sending binary data to a server via websockets. But now I'm just using Uint8 Arrays. So I assemble a new Uint8Array([with, the, data, I, need]) and send the buffer of this array (Unint8Array.buffer) to the server.

But now it could happen, that I need some Uint16 or Float32 Data within my request, mixed inside my Uint8 Data. Is there any way to achieve this and how.

EDIT: The length of the request data is unknown as I have to assemble the requests dynamic.

Thanks for any reply :)


Solution

  • Yes, you can do that, that's why types arrays have the separation of the array and the buffer it stores things in. Here's an example of two views of a buffer, one with bytes and one with words: Live Copy

    // Create the buffer
    var buf = new ArrayBuffer(10);
    
    // Create a byte view of it
    var a8 = new Int8Array(buf);
    
    // Create a word view of it
    var a16 = new Int16Array(buf, 2, 2);
    
    // Set a couple of words
    a16[0] = 0x1221;
    a16[1] = 0x2442;
    
    // Show the contents of the byte array
    var i;
    for (i = 0; i < a8.length; ++i) {
      console.log("0x" + a8[i].toString(16));
    }
    

    Output:

    0x0
    0x0
    0x21
    0x12
    0x42
    0x24
    0x0
    0x0
    0x0
    0x0
    

    There I've created the ArrayBuffer explicitly for clarity, but you can also do it implicitly: Live Copy (same output)

    // Create a byte view and underlying buffer
    var a8 = new Int8Array(10);
    
    // Create a word view of the byte view's buffer
    var a16 = new Int16Array(a8.buffer, 2, 2);
    
    // Set a couple of words
    a16[0] = 0x1221;
    a16[1] = 0x2442;
    
    // Show the contents of the byte array
    var i;
    for (i = 0; i < a8.length; ++i) {
      console.log("0x" + a8[i].toString(16));
    }
    

    EDIT: The length of the request data is unknown as I have to assemble the requests dynamic.

    If you have allocated a large enough ArrayBuffer, that's not necessarily a problem, you just need to create the view at the relevant starting point for (say) the rest of the length of the buffer. But you'll have to keep track of how big what you've written is at least after you've written it, so you know where to continue with other data.