@loaders.gl/core
Version:
Framework-independent loaders for 3D graphics formats
124 lines (101 loc) • 2.92 kB
JavaScript
import { getRegisteredLoaders } from './register-loaders';
import { normalizeLoader } from './loader-utils/normalize-loader';
const EXT_PATTERN = /[^.]+$/;
export function selectLoader(loaders, url = '', data = null, {
nothrow = false
} = {}) {
url = url || '';
if (loaders && !Array.isArray(loaders)) {
const loader = loaders;
normalizeLoader(loader);
return loader;
}
loaders = loaders || getRegisteredLoaders();
normalizeLoaders(loaders);
url = url.replace(/\?.*/, '');
let loader = null;
loader = loader || findLoaderByUrl(loaders, url);
loader = loader || findLoaderByExamingInitialData(loaders, data);
if (!loader) {
if (nothrow) {
return null;
}
throw new Error("No valid loader found for ".concat(url));
}
return loader;
}
function normalizeLoaders(loaders) {
for (const loader of loaders) {
normalizeLoader(loader);
}
}
function findLoaderByUrl(loaders, url) {
const match = url.match(EXT_PATTERN);
const extension = match && match[0];
const loader = extension && findLoaderByExtension(loaders, extension);
return loader;
}
function findLoaderByExtension(loaders, extension) {
extension = extension.toLowerCase();
for (const loader of loaders) {
for (const loaderExtension of loader.extensions) {
if (loaderExtension.toLowerCase() === extension) {
return loader;
}
}
}
return null;
}
function findLoaderByExamingInitialData(loaders, data) {
if (!data) {
return null;
}
for (const loader of loaders) {
if (typeof data === 'string') {
if (testText(data, loader)) {
return loader;
}
} else if (ArrayBuffer.isView(data)) {
if (testBinary(data.buffer, data.byteOffset, loader)) {
return loader;
}
} else if (data instanceof ArrayBuffer) {
const byteOffset = 0;
if (testBinary(data, byteOffset, loader)) {
return loader;
}
}
}
return null;
}
function testText(data, loader) {
return loader.testText && loader.testText(data);
}
function testBinary(data, byteOffset, loader) {
const type = Array.isArray(loader.test) ? 'array' : typeof loader.test;
switch (type) {
case 'function':
return loader.test(data, loader);
case 'string':
case 'array':
const tests = Array.isArray(loader.test) ? loader.test : [loader.test];
return tests.some(test => {
const magic = getMagicString(data, byteOffset, test.length);
return test === magic;
});
default:
return false;
}
}
function getMagicString(arrayBuffer, byteOffset, length) {
if (arrayBuffer.byteLength <= byteOffset + length) {
return '';
}
const dataView = new DataView(arrayBuffer);
let magic = '';
for (let i = 0; i < length; i++) {
magic += String.fromCharCode(dataView.getUint8(byteOffset + i));
}
return magic;
}
//# sourceMappingURL=select-loader.js.map