UNPKG

scratch-storage

Version:

Load and store project and asset files for Scratch 3.0

85 lines (76 loc) 3.25 kB
import {AssetId} from './Asset'; declare function require(name: 'fastestsmallesttextencoderdecoder'): { TextEncoder: typeof TextEncoder, TextDecoder: typeof TextDecoder }; declare function require(name: 'base64-js'): { fromByteArray: (data: Uint8Array) => string; }; // Use JS implemented TextDecoder and TextEncoder if it is not provided by the // browser. let _TextDecoder: typeof TextDecoder; let _TextEncoder: typeof TextEncoder; if (typeof TextDecoder === 'undefined' || typeof TextEncoder === 'undefined') { // Wait to require the text encoding polyfill until we know it's needed. const encoding = require('fastestsmallesttextencoderdecoder'); _TextDecoder = encoding.TextDecoder; _TextEncoder = encoding.TextEncoder; } else { _TextDecoder = TextDecoder; _TextEncoder = TextEncoder; } const memoizedToString = (function () { /** * The maximum length of a chunk before encoding it into base64. * * 32766 is a multiple of 3 so btoa does not need to use padding characters * except for the final chunk where that is fine. 32766 is also close to * 32768 so it is close to a size an memory allocator would prefer. * @constant {number} */ const BTOA_CHUNK_MAX_LENGTH = 32766; /** * An array cache of bytes to characters. * @constant {?Array.<string>} */ let fromCharCode: string[] | null = null; const strings = {}; return (assetId: AssetId, data: Uint8Array) => { if (!Object.prototype.hasOwnProperty.call(strings, assetId)) { if (typeof btoa === 'undefined') { // Use a library that does not need btoa to run. const base64js = require('base64-js'); strings[assetId] = base64js.fromByteArray(data); } else { // Native btoa is faster than javascript translation. Use js to // create a "binary" string and btoa to encode it. if (fromCharCode === null) { // Cache the first 256 characters for input byte values. fromCharCode = new Array(256); for (let i = 0; i < 256; i++) { fromCharCode[i] = String.fromCharCode(i); } } const {length} = data; let s = ''; // Iterate over chunks of the binary data. for (let i = 0, e = 0; i < length; i = e) { // Create small chunks to cause more small allocations and // less large allocations. e = Math.min(e + BTOA_CHUNK_MAX_LENGTH, length); let s_ = ''; for (let j = i; j < e; j += 1) { s_ += fromCharCode[data[j]]; } // Encode the latest chunk so the we create one big output // string instead of creating a big input string and then // one big output string. s += btoa(s_); } strings[assetId] = s; } } return strings[assetId]; }; }()); export {memoizedToString, _TextEncoder, _TextDecoder};