@loaders.gl/loader-utils
Version:
Framework-independent loaders for 3D graphics formats
111 lines (100 loc) • 3.27 kB
text/typescript
import {TypedArray} from '../../types';
/**
* compare two binary arrays for equality
* @param a
* @param b
* @param byteLength
*/
export function compareArrayBuffers(
arrayBuffer1: ArrayBuffer,
arrayBuffer2: ArrayBuffer,
byteLength?: number
): boolean {
byteLength = byteLength || arrayBuffer1.byteLength;
if (arrayBuffer1.byteLength < byteLength || arrayBuffer2.byteLength < byteLength) {
return false;
}
const array1 = new Uint8Array(arrayBuffer1);
const array2 = new Uint8Array(arrayBuffer2);
for (let i = 0; i < array1.length; ++i) {
if (array1[i] !== array2[i]) {
return false;
}
}
return true;
}
/**
* Concatenate a sequence of ArrayBuffers from arguments
* @return A concatenated ArrayBuffer
*/
export function concatenateArrayBuffers(...sources: (ArrayBuffer | Uint8Array)[]): ArrayBuffer {
return concatenateArrayBuffersFromArray(sources);
}
/**
* Concatenate a sequence of ArrayBuffers from array
* @return A concatenated ArrayBuffer
*/
export function concatenateArrayBuffersFromArray(
sources: (ArrayBuffer | Uint8Array)[]
): ArrayBuffer {
// Make sure all inputs are wrapped in typed arrays
const sourceArrays = sources.map((source2) =>
source2 instanceof ArrayBuffer ? new Uint8Array(source2) : source2
);
// Get length of all inputs
const byteLength = sourceArrays.reduce((length, typedArray) => length + typedArray.byteLength, 0);
// Allocate array with space for all inputs
const result = new Uint8Array(byteLength);
// Copy the subarrays
let offset = 0;
for (const sourceArray of sourceArrays) {
result.set(sourceArray, offset);
offset += sourceArray.byteLength;
}
// We work with ArrayBuffers, discard the typed array wrapper
return result.buffer;
}
/**
* Concatenate arbitrary count of typed arrays
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays
* @param - list of arrays. All arrays should be the same type
* @return A concatenated TypedArray
*/
export function concatenateTypedArrays<T>(...typedArrays: T[]): T {
// @ts-ignore
const arrays = typedArrays as TypedArray[];
// @ts-ignore
const TypedArrayConstructor = (arrays && arrays.length > 1 && arrays[0].constructor) || null;
if (!TypedArrayConstructor) {
throw new Error(
'"concatenateTypedArrays" - incorrect quantity of arguments or arguments have incompatible data types'
);
}
const sumLength = arrays.reduce((acc, value) => acc + value.length, 0);
// @ts-ignore typescript does not like dynamic constructors
const result = new TypedArrayConstructor(sumLength);
let offset = 0;
for (const array of arrays) {
result.set(array, offset);
offset += array.length;
}
return result;
}
/**
* Copy a view of an ArrayBuffer into new ArrayBuffer with byteOffset = 0
* @param arrayBuffer
* @param byteOffset
* @param byteLength
*/
export function sliceArrayBuffer(
arrayBuffer: ArrayBuffer,
byteOffset: number,
byteLength?: number
): ArrayBuffer {
const subArray =
byteLength !== undefined
? new Uint8Array(arrayBuffer).subarray(byteOffset, byteOffset + byteLength)
: new Uint8Array(arrayBuffer).subarray(byteOffset);
const arrayCopy = new Uint8Array(subArray);
return arrayCopy.buffer;
}