web-dev-qa-db-ja.com

javascriptでArrayBufferにバイト、マルチバイト、バッファを追加する方法は?

JavascriptのArrayBufferまたはTypedArraysには、appendByte()、appendBytes()、またはappendBuffer()メソッドの種類はありません。 ArrayBufferを一度に1つの値で埋めたい場合、どうすればよいですか?

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);
15
codneto

新しいTypedArrayで新しいArrayBufferを作成できますが、既存のバッファーのサイズを変更することはできません

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;
}

今できること

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

異なるタイプを使用する場合は、Uint8Arrayを経由します。最小単位はbyteです。つまり、.

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

これは、.lengthが期待どおりに機能することを意味します。これを選択した型付き配列に変換できます(ただし、バッファの.byteLengthを受け入れる型であることを確認してください)


ここから、データを連結するための任意のメソッドを実装できます。

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]
13
Paul S.

Paulの答えにより、1つのTypedArrayを既存のTypedArrayに連結できます。 ES6では、次の関数を使用して複数のTypedArrayを連結できます。

function concatenate(resultConstructor, ...arrays) {
    let totalLength = 0;
    for (const arr of arrays) {
        totalLength += arr.length;
    }
    const result = new resultConstructor(totalLength);
    let offset = 0;
    for (const arr of arrays) {
        result.set(arr, offset);
        offset += arr.length;
    }
    return result;
}

const ta = concatenate(Uint8Array,
    Uint8Array.of(1, 2), Uint8Array.of(3, 4));
console.log(ta); // Uint8Array [1, 2, 3, 4]
console.log(ta.buffer.byteLength); // 4

新しいバイトを追加するには:

const byte = 3;
concatenate(Uint8Array, Uint8Array.of(1, 2), Uint8Array.of(byte));

このメソッドは ExploringJS にあります。

3
newguy