How to append bytes, multi-bytes and buffer to ArrayBuffer in javascript?

codneto picture codneto · Nov 13, 2015 · Viewed 32.2k times · Source

Javascript ArrayBuffer or TypedArrays dont have any kind of appendByte(), appendBytes(), or appendBuffer() methods. So if I want to fill an ArrayBuffer one value at a time, how do I do it?

var firstVal = 0xAB;              // 1 byte
var secondVal = 0x3D7F            // 2 bytes
var anotherUint8Array = someArr;

var buffer = new ArrayBuffer();   // I don't know the length yet
var bufferArr = new UInt8Array(buffer);

// following methods do not exist. What are the alternatives for each??
bufferArr.appendByte(firstVal);
bufferArr.appendBytes(secondVal);
bufferArr.appendBuffer(anotherUint8Array);

Answer

Paul S. picture Paul S. · Nov 13, 2015

You can create a new TypedArray with a new ArrayBuffer, but you can't change the size of an existing buffer

function concatTypedArrays(a, b) { // a, b TypedArray of same type
    var c = new (a.constructor)(a.length + b.length);
    c.set(a, 0);
    c.set(b, a.length);
    return c;
}

Now can do

var a = new Uint8Array(2),
    b = new Uint8Array(3);
a[0] = 1; a[1] = 2;
b[0] = 3; b[1] = 4;
concatTypedArrays(a, b); // [1, 2, 3, 4, 0] Uint8Array length 5

If you want to use different types, go via Uint8Array as the smallest unit is a byte, i.e.

function concatBuffers(a, b) {
    return concatTypedArrays(
        new Uint8Array(a.buffer || a), 
        new Uint8Array(b.buffer || b)
    ).buffer;
}

This means .length will work as expected, you could now convert this to your typed array of choice (make sure it's a type that would accept the .byteLength of the buffer though)


From here, you could now implement any method you like for concatenating your data, e.g.

function concatBytes(ui8a, byte) {
    var b = new Uint8Array(1);
    b[0] = byte;
    return concatTypedArrays(ui8a, b);
}

var u8 = new Uint8Array(0);
u8 = concatBytes(u8, 0x80); // [128]