@loaders.gl/loader-utils
Version:
Framework-independent loaders for 3D graphics formats
90 lines (89 loc) • 3.42 kB
JavaScript
// loaders./gl, MIT license
import { padToNBytes } from "./memory-copy-utils.js";
/**
* Helper function that pads a string with spaces to fit a certain byte alignment
* @param string
* @param byteAlignment
* @returns
*
* @todo PERFORMANCE IDEA: No need to copy string twice...
*/
export function padStringToByteAlignment(string, byteAlignment) {
const length = string.length;
const paddedLength = Math.ceil(length / byteAlignment) * byteAlignment; // Round up to the required alignment
const padding = paddedLength - length;
let whitespace = '';
for (let i = 0; i < padding; ++i) {
whitespace += ' ';
}
return string + whitespace;
}
/**
*
* @param dataView
* @param byteOffset
* @param string
* @param byteLength
* @returns
*/
export function copyStringToDataView(dataView, byteOffset, string, byteLength) {
if (dataView) {
for (let i = 0; i < byteLength; i++) {
dataView.setUint8(byteOffset + i, string.charCodeAt(i));
}
}
return byteOffset + byteLength;
}
export function copyBinaryToDataView(dataView, byteOffset, binary, byteLength) {
if (dataView) {
for (let i = 0; i < byteLength; i++) {
dataView.setUint8(byteOffset + i, binary[i]);
}
}
return byteOffset + byteLength;
}
/**
* Copy sourceBuffer to dataView with some padding
*
* @param dataView - destination data container. If null - only new offset is calculated
* @param byteOffset - destination byte offset to copy to
* @param sourceBuffer - source data buffer
* @param padding - pad the resulting array to multiple of "padding" bytes. Additional bytes are filled with 0x20 (ASCII space)
*
* @return new byteOffset of resulting dataView
*/
export function copyPaddedArrayBufferToDataView(dataView, byteOffset, sourceBuffer, padding) {
const paddedLength = padToNBytes(sourceBuffer.byteLength, padding);
const padLength = paddedLength - sourceBuffer.byteLength;
if (dataView) {
// Copy array
const targetArray = new Uint8Array(dataView.buffer, dataView.byteOffset + byteOffset, sourceBuffer.byteLength);
const sourceArray = new Uint8Array(sourceBuffer);
targetArray.set(sourceArray);
// Add PADDING
for (let i = 0; i < padLength; ++i) {
// json chunk is padded with spaces (ASCII 0x20)
dataView.setUint8(byteOffset + sourceBuffer.byteLength + i, 0x20);
}
}
byteOffset += paddedLength;
return byteOffset;
}
/**
* Copy string to dataView with some padding
*
* @param {DataView | null} dataView - destination data container. If null - only new offset is calculated
* @param {number} byteOffset - destination byte offset to copy to
* @param {string} string - source string
* @param {number} padding - pad the resulting array to multiple of "padding" bytes. Additional bytes are filled with 0x20 (ASCII space)
*
* @return new byteOffset of resulting dataView
*/
export function copyPaddedStringToDataView(dataView, byteOffset, string, padding) {
const textEncoder = new TextEncoder();
// PERFORMANCE IDEA: We encode twice, once to get size and once to store
// PERFORMANCE IDEA: Use TextEncoder.encodeInto() to avoid temporary copy
const stringBuffer = textEncoder.encode(string);
byteOffset = copyPaddedArrayBufferToDataView(dataView, byteOffset, stringBuffer, padding);
return byteOffset;
}