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