I need to bine 2 parts of 2 existing arrayBuffers into a new one.
I am building a parser and the data es in arraybuffers of random sizes, the data will spill over the end of one, into the beginning of the other. So I need to create a new output buffer and copy in a portion of the end of one buffer and a portion of the beginning of the other. The output will just be an Arraybuffer.
Starting out with this demo, I was going to make Uint8Arrays with some offsets then use set, the problem is certain binations throw Invalid typed array length
. I will not know the length of each array or offsets beforehand.
var buffer1 = new ArrayBuffer(8);
var buffer2 = new ArrayBuffer(8);
var buffer3 = new ArrayBuffer(8);
var uint8_1 = new Uint8Array(buffer1);
var uint8_2 = new Uint8Array(buffer2);
var uint8_3 = new Uint8Array(buffer3);
uint8_1.fill(1);
uint8_2.fill(2);
var uint8_1_slice = new Uint8Array(buffer1 , 0 , 3);
var uint8_2_slice = new Uint8Array(buffer2 , 4, 7);
For this demo need to get buffer3 to be 1,1,1,1,2,2,2,2.
Cannot Use Slice
I need to bine 2 parts of 2 existing arrayBuffers into a new one.
I am building a parser and the data es in arraybuffers of random sizes, the data will spill over the end of one, into the beginning of the other. So I need to create a new output buffer and copy in a portion of the end of one buffer and a portion of the beginning of the other. The output will just be an Arraybuffer.
Starting out with this demo, I was going to make Uint8Arrays with some offsets then use set, the problem is certain binations throw Invalid typed array length
. I will not know the length of each array or offsets beforehand.
var buffer1 = new ArrayBuffer(8);
var buffer2 = new ArrayBuffer(8);
var buffer3 = new ArrayBuffer(8);
var uint8_1 = new Uint8Array(buffer1);
var uint8_2 = new Uint8Array(buffer2);
var uint8_3 = new Uint8Array(buffer3);
uint8_1.fill(1);
uint8_2.fill(2);
var uint8_1_slice = new Uint8Array(buffer1 , 0 , 3);
var uint8_2_slice = new Uint8Array(buffer2 , 4, 7);
For this demo need to get buffer3 to be 1,1,1,1,2,2,2,2.
Share Improve this question edited Sep 15, 2016 at 3:22 brianxautumn asked Sep 15, 2016 at 2:39 brianxautumnbrianxautumn 1,1628 silver badges21 bronze badgesCannot Use Slice
2 Answers
Reset to default 4I have seen some people only use array.length
. It's fine as long as the array is only 1 byte per element. It's also fine if the other typed arrays are filled up but in this example a2
isn't. That is why it's better to use byteLength
this is also how Blob constructor concatenate the parts.
// Concatenate a mix of typed arrays
function concatenate(...arrays) {
// Calculate byteSize from all arrays
let size = arrays.reduce((a,b) => a + b.byteLength, 0)
// Allcolate a new buffer
let result = new Uint8Array(size)
// Build the new array
let offset = 0
for (let arr of arrays) {
result.set(arr, offset)
offset += arr.byteLength
}
return result
}
// the total length of 1-3 = 5
// the total byteLength of 1-3 = 6
let a1 = Uint8Array.of(1, 2) // [1, 2]
let a2 = Uint16Array.of(3) // [3] just for the fun of it 16 takes up 2 bytes
let a3 = Uint8Array.of(4, 5) // [4, 5]
concatenate(a1, a2, a3) // [1, 2, 3, 0, 4, 5]
/********/
var blob = new Blob([a1, a2, a3])
var res = new Response(blob)
res.arrayBuffer().then(buffer => console.log(new Uint8Array(buffer)))
// [1, 2, 3, 0, 4, 5]
For this demo need to get buffer3 to be 1,1,1,1,2,2,2,2.
You can use for
loop, set uint8_3
to uint8_1
value if variable n
is less than uint8_1.byteLength / 2
else set uint8_3
to value at uint8_2
.
var len = 8;
var buffer1 = new ArrayBuffer(len);
var buffer2 = new ArrayBuffer(len);
var buffer3 = new ArrayBuffer(len);
var uint8_1 = new Uint8Array(buffer1);
var uint8_2 = new Uint8Array(buffer2);
var uint8_3 = new Uint8Array(buffer3);
uint8_1.fill(1);
uint8_2.fill(2);
// `len` : uint8_1.byteLength / 2 + uint8_2.byteLength / 2
for (var n = 0; n < len; n++) {
uint8_3[n] = n < len / 2 ? uint8_1[n] : uint8_2[n];
}
console.log(uint8_3);