UNPKG

hic-straw

Version:

Utilities for reading .files (contact matrix files)

1,749 lines (1,369 loc) 372 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.HicStraw = factory()); })(this, (function () { 'use strict'; var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; var check = function (it) { return it && it.Math == Math && it; }; // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 var global$a = // eslint-disable-next-line es-x/no-global-this -- safe check(typeof globalThis == 'object' && globalThis) || check(typeof window == 'object' && window) || // eslint-disable-next-line no-restricted-globals -- safe check(typeof self == 'object' && self) || check(typeof commonjsGlobal == 'object' && commonjsGlobal) || // eslint-disable-next-line no-new-func -- fallback function () { return this; }() || Function('return this')(); var fails$7 = function (exec) { try { return !!exec(); } catch (error) { return true; } }; var fails$6 = fails$7; // Detect IE8's incomplete defineProperty implementation var descriptors = !fails$6(function () { // eslint-disable-next-line es-x/no-object-defineproperty -- required for testing return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7; }); var makeBuiltIn$2 = {exports: {}}; // https://tc39.es/ecma262/#sec-iscallable var isCallable$8 = function (argument) { return typeof argument == 'function'; }; var fails$5 = fails$7; var functionBindNative = !fails$5(function () { // eslint-disable-next-line es-x/no-function-prototype-bind -- safe var test = function () { /* empty */ }.bind(); // eslint-disable-next-line no-prototype-builtins -- safe return typeof test != 'function' || test.hasOwnProperty('prototype'); }); var NATIVE_BIND$1 = functionBindNative; var FunctionPrototype$1 = Function.prototype; var bind = FunctionPrototype$1.bind; var call$3 = FunctionPrototype$1.call; var uncurryThis$5 = NATIVE_BIND$1 && bind.bind(call$3, call$3); var functionUncurryThis = NATIVE_BIND$1 ? function (fn) { return fn && uncurryThis$5(fn); } : function (fn) { return fn && function () { return call$3.apply(fn, arguments); }; }; // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec var isNullOrUndefined$2 = function (it) { return it === null || it === undefined; }; var isNullOrUndefined$1 = isNullOrUndefined$2; var $TypeError$5 = TypeError; // `RequireObjectCoercible` abstract operation // https://tc39.es/ecma262/#sec-requireobjectcoercible var requireObjectCoercible$1 = function (it) { if (isNullOrUndefined$1(it)) throw $TypeError$5("Can't call method on " + it); return it; }; var requireObjectCoercible = requireObjectCoercible$1; var $Object$1 = Object; // `ToObject` abstract operation // https://tc39.es/ecma262/#sec-toobject var toObject$1 = function (argument) { return $Object$1(requireObjectCoercible(argument)); }; var uncurryThis$4 = functionUncurryThis; var toObject = toObject$1; var hasOwnProperty = uncurryThis$4({}.hasOwnProperty); // `HasOwnProperty` abstract operation // https://tc39.es/ecma262/#sec-hasownproperty // eslint-disable-next-line es-x/no-object-hasown -- safe var hasOwnProperty_1 = Object.hasOwn || function hasOwn(it, key) { return hasOwnProperty(toObject(it), key); }; var DESCRIPTORS$6 = descriptors; var hasOwn$3 = hasOwnProperty_1; var FunctionPrototype = Function.prototype; // eslint-disable-next-line es-x/no-object-getownpropertydescriptor -- safe var getDescriptor = DESCRIPTORS$6 && Object.getOwnPropertyDescriptor; var EXISTS$1 = hasOwn$3(FunctionPrototype, 'name'); // additional protection from minified / mangled / dropped function names var PROPER = EXISTS$1 && function something() { /* empty */ }.name === 'something'; var CONFIGURABLE$1 = EXISTS$1 && (!DESCRIPTORS$6 || DESCRIPTORS$6 && getDescriptor(FunctionPrototype, 'name').configurable); var functionName = { EXISTS: EXISTS$1, PROPER: PROPER, CONFIGURABLE: CONFIGURABLE$1 }; var global$9 = global$a; // eslint-disable-next-line es-x/no-object-defineproperty -- safe var defineProperty$2 = Object.defineProperty; var defineGlobalProperty$1 = function (key, value) { try { defineProperty$2(global$9, key, { value: value, configurable: true, writable: true }); } catch (error) { global$9[key] = value; } return value; }; var global$8 = global$a; var defineGlobalProperty = defineGlobalProperty$1; var SHARED = '__core-js_shared__'; var store$3 = global$8[SHARED] || defineGlobalProperty(SHARED, {}); var sharedStore = store$3; var uncurryThis$3 = functionUncurryThis; var isCallable$7 = isCallable$8; var store$2 = sharedStore; var functionToString = uncurryThis$3(Function.toString); // this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper if (!isCallable$7(store$2.inspectSource)) { store$2.inspectSource = function (it) { return functionToString(it); }; } var inspectSource$1 = store$2.inspectSource; var global$7 = global$a; var isCallable$6 = isCallable$8; var WeakMap$1 = global$7.WeakMap; var weakMapBasicDetection = isCallable$6(WeakMap$1) && /native code/.test(String(WeakMap$1)); var isCallable$5 = isCallable$8; var documentAll = typeof document == 'object' && document.all; // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot var SPECIAL_DOCUMENT_ALL = typeof documentAll == 'undefined' && documentAll !== undefined; var isObject$5 = SPECIAL_DOCUMENT_ALL ? function (it) { return typeof it == 'object' ? it !== null : isCallable$5(it) || it === documentAll; } : function (it) { return typeof it == 'object' ? it !== null : isCallable$5(it); }; var objectDefineProperty = {}; var global$6 = global$a; var isObject$4 = isObject$5; var document$1 = global$6.document; // typeof document.createElement is 'object' in old IE var EXISTS = isObject$4(document$1) && isObject$4(document$1.createElement); var documentCreateElement = function (it) { return EXISTS ? document$1.createElement(it) : {}; }; var DESCRIPTORS$5 = descriptors; var fails$4 = fails$7; var createElement = documentCreateElement; // Thanks to IE8 for its funny defineProperty var ie8DomDefine = !DESCRIPTORS$5 && !fails$4(function () { // eslint-disable-next-line es-x/no-object-defineproperty -- required for testing return Object.defineProperty(createElement('div'), 'a', { get: function () { return 7; } }).a != 7; }); var DESCRIPTORS$4 = descriptors; var fails$3 = fails$7; // V8 ~ Chrome 36- // https://bugs.chromium.org/p/v8/issues/detail?id=3334 var v8PrototypeDefineBug = DESCRIPTORS$4 && fails$3(function () { // eslint-disable-next-line es-x/no-object-defineproperty -- required for testing return Object.defineProperty(function () { /* empty */ }, 'prototype', { value: 42, writable: false }).prototype != 42; }); var isObject$3 = isObject$5; var $String$1 = String; var $TypeError$4 = TypeError; // `Assert: Type(argument) is Object` var anObject$2 = function (argument) { if (isObject$3(argument)) return argument; throw $TypeError$4($String$1(argument) + ' is not an object'); }; var NATIVE_BIND = functionBindNative; var call$2 = Function.prototype.call; var functionCall = NATIVE_BIND ? call$2.bind(call$2) : function () { return call$2.apply(call$2, arguments); }; var global$5 = global$a; var isCallable$4 = isCallable$8; var aFunction = function (argument) { return isCallable$4(argument) ? argument : undefined; }; var getBuiltIn$2 = function (namespace, method) { return arguments.length < 2 ? aFunction(global$5[namespace]) : global$5[namespace] && global$5[namespace][method]; }; var uncurryThis$2 = functionUncurryThis; var objectIsPrototypeOf = uncurryThis$2({}.isPrototypeOf); var getBuiltIn$1 = getBuiltIn$2; var engineUserAgent = getBuiltIn$1('navigator', 'userAgent') || ''; var global$4 = global$a; var userAgent = engineUserAgent; var process$1 = global$4.process; var Deno = global$4.Deno; var versions = process$1 && process$1.versions || Deno && Deno.version; var v8 = versions && versions.v8; var match, version; if (v8) { match = v8.split('.'); // in old Chrome, versions of V8 isn't V8 = Chrome / 10 // but their correct versions are not interesting for us version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]); } // BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0` // so check `userAgent` even if `.v8` exists, but 0 if (!version && userAgent) { match = userAgent.match(/Edge\/(\d+)/); if (!match || match[1] >= 74) { match = userAgent.match(/Chrome\/(\d+)/); if (match) version = +match[1]; } } var engineV8Version = version; /* eslint-disable es-x/no-symbol -- required for testing */ var V8_VERSION = engineV8Version; var fails$2 = fails$7; // eslint-disable-next-line es-x/no-object-getownpropertysymbols -- required for testing var symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$2(function () { var symbol = Symbol(); // Chrome 38 Symbol has incorrect toString conversion // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances return !String(symbol) || !(Object(symbol) instanceof Symbol) || // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances !Symbol.sham && V8_VERSION && V8_VERSION < 41; }); /* eslint-disable es-x/no-symbol -- required for testing */ var NATIVE_SYMBOL$1 = symbolConstructorDetection; var useSymbolAsUid = NATIVE_SYMBOL$1 && !Symbol.sham && typeof Symbol.iterator == 'symbol'; var getBuiltIn = getBuiltIn$2; var isCallable$3 = isCallable$8; var isPrototypeOf = objectIsPrototypeOf; var USE_SYMBOL_AS_UID$1 = useSymbolAsUid; var $Object = Object; var isSymbol$2 = USE_SYMBOL_AS_UID$1 ? function (it) { return typeof it == 'symbol'; } : function (it) { var $Symbol = getBuiltIn('Symbol'); return isCallable$3($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it)); }; var $String = String; var tryToString$1 = function (argument) { try { return $String(argument); } catch (error) { return 'Object'; } }; var isCallable$2 = isCallable$8; var tryToString = tryToString$1; var $TypeError$3 = TypeError; // `Assert: IsCallable(argument) is true` var aCallable$1 = function (argument) { if (isCallable$2(argument)) return argument; throw $TypeError$3(tryToString(argument) + ' is not a function'); }; var aCallable = aCallable$1; var isNullOrUndefined = isNullOrUndefined$2; // `GetMethod` abstract operation // https://tc39.es/ecma262/#sec-getmethod var getMethod$1 = function (V, P) { var func = V[P]; return isNullOrUndefined(func) ? undefined : aCallable(func); }; var call$1 = functionCall; var isCallable$1 = isCallable$8; var isObject$2 = isObject$5; var $TypeError$2 = TypeError; // `OrdinaryToPrimitive` abstract operation // https://tc39.es/ecma262/#sec-ordinarytoprimitive var ordinaryToPrimitive$1 = function (input, pref) { var fn, val; if (pref === 'string' && isCallable$1(fn = input.toString) && !isObject$2(val = call$1(fn, input))) return val; if (isCallable$1(fn = input.valueOf) && !isObject$2(val = call$1(fn, input))) return val; if (pref !== 'string' && isCallable$1(fn = input.toString) && !isObject$2(val = call$1(fn, input))) return val; throw $TypeError$2("Can't convert object to primitive value"); }; var shared$3 = {exports: {}}; var store$1 = sharedStore; (shared$3.exports = function (key, value) { return store$1[key] || (store$1[key] = value !== undefined ? value : {}); })('versions', []).push({ version: '3.25.0', mode: 'global', copyright: '© 2014-2022 Denis Pushkarev (zloirock.ru)', license: 'https://github.com/zloirock/core-js/blob/v3.25.0/LICENSE', source: 'https://github.com/zloirock/core-js' }); var uncurryThis$1 = functionUncurryThis; var id = 0; var postfix = Math.random(); var toString = uncurryThis$1(1.0.toString); var uid$2 = function (key) { return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36); }; var global$3 = global$a; var shared$2 = shared$3.exports; var hasOwn$2 = hasOwnProperty_1; var uid$1 = uid$2; var NATIVE_SYMBOL = symbolConstructorDetection; var USE_SYMBOL_AS_UID = useSymbolAsUid; var WellKnownSymbolsStore = shared$2('wks'); var Symbol$1 = global$3.Symbol; var symbolFor = Symbol$1 && Symbol$1['for']; var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid$1; var wellKnownSymbol$1 = function (name) { if (!hasOwn$2(WellKnownSymbolsStore, name) || !(NATIVE_SYMBOL || typeof WellKnownSymbolsStore[name] == 'string')) { var description = 'Symbol.' + name; if (NATIVE_SYMBOL && hasOwn$2(Symbol$1, name)) { WellKnownSymbolsStore[name] = Symbol$1[name]; } else if (USE_SYMBOL_AS_UID && symbolFor) { WellKnownSymbolsStore[name] = symbolFor(description); } else { WellKnownSymbolsStore[name] = createWellKnownSymbol(description); } } return WellKnownSymbolsStore[name]; }; var call = functionCall; var isObject$1 = isObject$5; var isSymbol$1 = isSymbol$2; var getMethod = getMethod$1; var ordinaryToPrimitive = ordinaryToPrimitive$1; var wellKnownSymbol = wellKnownSymbol$1; var $TypeError$1 = TypeError; var TO_PRIMITIVE = wellKnownSymbol('toPrimitive'); // `ToPrimitive` abstract operation // https://tc39.es/ecma262/#sec-toprimitive var toPrimitive$1 = function (input, pref) { if (!isObject$1(input) || isSymbol$1(input)) return input; var exoticToPrim = getMethod(input, TO_PRIMITIVE); var result; if (exoticToPrim) { if (pref === undefined) pref = 'default'; result = call(exoticToPrim, input, pref); if (!isObject$1(result) || isSymbol$1(result)) return result; throw $TypeError$1("Can't convert object to primitive value"); } if (pref === undefined) pref = 'number'; return ordinaryToPrimitive(input, pref); }; var toPrimitive = toPrimitive$1; var isSymbol = isSymbol$2; // `ToPropertyKey` abstract operation // https://tc39.es/ecma262/#sec-topropertykey var toPropertyKey$1 = function (argument) { var key = toPrimitive(argument, 'string'); return isSymbol(key) ? key : key + ''; }; var DESCRIPTORS$3 = descriptors; var IE8_DOM_DEFINE = ie8DomDefine; var V8_PROTOTYPE_DEFINE_BUG = v8PrototypeDefineBug; var anObject$1 = anObject$2; var toPropertyKey = toPropertyKey$1; var $TypeError = TypeError; // eslint-disable-next-line es-x/no-object-defineproperty -- safe var $defineProperty = Object.defineProperty; // eslint-disable-next-line es-x/no-object-getownpropertydescriptor -- safe var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; var ENUMERABLE = 'enumerable'; var CONFIGURABLE = 'configurable'; var WRITABLE = 'writable'; // `Object.defineProperty` method // https://tc39.es/ecma262/#sec-object.defineproperty objectDefineProperty.f = DESCRIPTORS$3 ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) { anObject$1(O); P = toPropertyKey(P); anObject$1(Attributes); if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) { var current = $getOwnPropertyDescriptor(O, P); if (current && current[WRITABLE]) { O[P] = Attributes.value; Attributes = { configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE], enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE], writable: false }; } } return $defineProperty(O, P, Attributes); } : $defineProperty : function defineProperty(O, P, Attributes) { anObject$1(O); P = toPropertyKey(P); anObject$1(Attributes); if (IE8_DOM_DEFINE) try { return $defineProperty(O, P, Attributes); } catch (error) { /* empty */ } if ('get' in Attributes || 'set' in Attributes) throw $TypeError('Accessors not supported'); if ('value' in Attributes) O[P] = Attributes.value; return O; }; var createPropertyDescriptor$1 = function (bitmap, value) { return { enumerable: !(bitmap & 1), configurable: !(bitmap & 2), writable: !(bitmap & 4), value: value }; }; var DESCRIPTORS$2 = descriptors; var definePropertyModule = objectDefineProperty; var createPropertyDescriptor = createPropertyDescriptor$1; var createNonEnumerableProperty$1 = DESCRIPTORS$2 ? function (object, key, value) { return definePropertyModule.f(object, key, createPropertyDescriptor(1, value)); } : function (object, key, value) { object[key] = value; return object; }; var shared$1 = shared$3.exports; var uid = uid$2; var keys = shared$1('keys'); var sharedKey$1 = function (key) { return keys[key] || (keys[key] = uid(key)); }; var NATIVE_WEAK_MAP = weakMapBasicDetection; var global$2 = global$a; var uncurryThis = functionUncurryThis; var isObject = isObject$5; var createNonEnumerableProperty = createNonEnumerableProperty$1; var hasOwn$1 = hasOwnProperty_1; var shared = sharedStore; var sharedKey = sharedKey$1; var OBJECT_ALREADY_INITIALIZED = 'Object already initialized'; var TypeError$1 = global$2.TypeError; var WeakMap = global$2.WeakMap; var set, get, has; var enforce = function (it) { return has(it) ? get(it) : set(it, {}); }; var getterFor = function (TYPE) { return function (it) { var state; if (!isObject(it) || (state = get(it)).type !== TYPE) { throw TypeError$1('Incompatible receiver, ' + TYPE + ' required'); } return state; }; }; if (NATIVE_WEAK_MAP || shared.state) { var store = shared.state || (shared.state = new WeakMap()); var wmget = uncurryThis(store.get); var wmhas = uncurryThis(store.has); var wmset = uncurryThis(store.set); set = function (it, metadata) { if (wmhas(store, it)) throw TypeError$1(OBJECT_ALREADY_INITIALIZED); metadata.facade = it; wmset(store, it, metadata); return metadata; }; get = function (it) { return wmget(store, it) || {}; }; has = function (it) { return wmhas(store, it); }; } else { var STATE = sharedKey('state'); set = function (it, metadata) { if (hasOwn$1(it, STATE)) throw TypeError$1(OBJECT_ALREADY_INITIALIZED); metadata.facade = it; createNonEnumerableProperty(it, STATE, metadata); return metadata; }; get = function (it) { return hasOwn$1(it, STATE) ? it[STATE] : {}; }; has = function (it) { return hasOwn$1(it, STATE); }; } var internalState = { set: set, get: get, has: has, enforce: enforce, getterFor: getterFor }; var fails$1 = fails$7; var isCallable = isCallable$8; var hasOwn = hasOwnProperty_1; var DESCRIPTORS$1 = descriptors; var CONFIGURABLE_FUNCTION_NAME = functionName.CONFIGURABLE; var inspectSource = inspectSource$1; var InternalStateModule = internalState; var enforceInternalState = InternalStateModule.enforce; var getInternalState = InternalStateModule.get; // eslint-disable-next-line es-x/no-object-defineproperty -- safe var defineProperty$1 = Object.defineProperty; var CONFIGURABLE_LENGTH = DESCRIPTORS$1 && !fails$1(function () { return defineProperty$1(function () { /* empty */ }, 'length', { value: 8 }).length !== 8; }); var TEMPLATE = String(String).split('String'); var makeBuiltIn$1 = makeBuiltIn$2.exports = function (value, name, options) { if (String(name).slice(0, 7) === 'Symbol(') { name = '[' + String(name).replace(/^Symbol\(([^)]*)\)/, '$1') + ']'; } if (options && options.getter) name = 'get ' + name; if (options && options.setter) name = 'set ' + name; if (!hasOwn(value, 'name') || CONFIGURABLE_FUNCTION_NAME && value.name !== name) { if (DESCRIPTORS$1) defineProperty$1(value, 'name', { value: name, configurable: true });else value.name = name; } if (CONFIGURABLE_LENGTH && options && hasOwn(options, 'arity') && value.length !== options.arity) { defineProperty$1(value, 'length', { value: options.arity }); } try { if (options && hasOwn(options, 'constructor') && options.constructor) { if (DESCRIPTORS$1) defineProperty$1(value, 'prototype', { writable: false }); // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable } else if (value.prototype) value.prototype = undefined; } catch (error) { /* empty */ } var state = enforceInternalState(value); if (!hasOwn(state, 'source')) { state.source = TEMPLATE.join(typeof name == 'string' ? name : ''); } return value; }; // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative // eslint-disable-next-line no-extend-native -- required Function.prototype.toString = makeBuiltIn$1(function toString() { return isCallable(this) && getInternalState(this).source || inspectSource(this); }, 'toString'); var makeBuiltIn = makeBuiltIn$2.exports; var defineProperty = objectDefineProperty; var defineBuiltInAccessor$1 = function (target, name, descriptor) { if (descriptor.get) makeBuiltIn(descriptor.get, name, { getter: true }); if (descriptor.set) makeBuiltIn(descriptor.set, name, { setter: true }); return defineProperty.f(target, name, descriptor); }; var anObject = anObject$2; // `RegExp.prototype.flags` getter implementation // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags var regexpFlags = function () { var that = anObject(this); var result = ''; if (that.hasIndices) result += 'd'; if (that.global) result += 'g'; if (that.ignoreCase) result += 'i'; if (that.multiline) result += 'm'; if (that.dotAll) result += 's'; if (that.unicode) result += 'u'; if (that.unicodeSets) result += 'v'; if (that.sticky) result += 'y'; return result; }; var global$1 = global$a; var DESCRIPTORS = descriptors; var defineBuiltInAccessor = defineBuiltInAccessor$1; var regExpFlags = regexpFlags; var fails = fails$7; // babel-minify and Closure Compiler transpiles RegExp('.', 'd') -> /./d and it causes SyntaxError var RegExp = global$1.RegExp; var RegExpPrototype = RegExp.prototype; var FORCED = DESCRIPTORS && fails(function () { var INDICES_SUPPORT = true; try { RegExp('.', 'd'); } catch (error) { INDICES_SUPPORT = false; } var O = {}; // modern V8 bug var calls = ''; var expected = INDICES_SUPPORT ? 'dgimsy' : 'gimsy'; var addGetter = function (key, chr) { // eslint-disable-next-line es-x/no-object-defineproperty -- safe Object.defineProperty(O, key, { get: function () { calls += chr; return true; } }); }; var pairs = { dotAll: 's', global: 'g', ignoreCase: 'i', multiline: 'm', sticky: 'y' }; if (INDICES_SUPPORT) pairs.hasIndices = 'd'; for (var key in pairs) addGetter(key, pairs[key]); // eslint-disable-next-line es-x/no-object-getownpropertydescriptor -- safe var result = Object.getOwnPropertyDescriptor(RegExpPrototype, 'flags').get.call(O); return result !== expected || calls !== expected; }); // `RegExp.prototype.flags` getter // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags if (FORCED) defineBuiltInAccessor(RegExpPrototype, 'flags', { configurable: true, get: regExpFlags }); var Zlib = { Huffman: {}, Util: {}, CRC32: {} }; /** * Compression Method * @enum {number} */ Zlib.CompressionMethod = { DEFLATE: 8, RESERVED: 15 }; /** * @param {Object=} opt_params options. * @constructor */ Zlib.Zip = function (opt_params) { opt_params = opt_params || {}; /** @type {Array.<{ * buffer: !(Array.<number>|Uint8Array), * option: Object, * compressed: boolean, * encrypted: boolean, * size: number, * crc32: number * }>} */ this.files = []; /** @type {(Array.<number>|Uint8Array)} */ this.comment = opt_params['comment']; /** @type {(Array.<number>|Uint8Array)} */ this.password; }; /** * @enum {number} */ Zlib.Zip.CompressionMethod = { STORE: 0, DEFLATE: 8 }; /** * @enum {number} */ Zlib.Zip.OperatingSystem = { MSDOS: 0, UNIX: 3, MACINTOSH: 7 }; /** * @enum {number} */ Zlib.Zip.Flags = { ENCRYPT: 0x0001, DESCRIPTOR: 0x0008, UTF8: 0x0800 }; /** * @type {Array.<number>} * @const */ Zlib.Zip.FileHeaderSignature = [0x50, 0x4b, 0x01, 0x02]; /** * @type {Array.<number>} * @const */ Zlib.Zip.LocalFileHeaderSignature = [0x50, 0x4b, 0x03, 0x04]; /** * @type {Array.<number>} * @const */ Zlib.Zip.CentralDirectorySignature = [0x50, 0x4b, 0x05, 0x06]; /** * @param {Array.<number>|Uint8Array} input * @param {Object=} opt_params options. */ Zlib.Zip.prototype.addFile = function (input, opt_params) { opt_params = opt_params || {}; /** @type {string} */ opt_params['filename']; /** @type {boolean} */ var compressed; /** @type {number} */ var size = input.length; /** @type {number} */ var crc32 = 0; if (input instanceof Array) { input = new Uint8Array(input); } // default if (typeof opt_params['compressionMethod'] !== 'number') { opt_params['compressionMethod'] = Zlib.Zip.CompressionMethod.DEFLATE; } // その場で圧縮する場合 if (opt_params['compress']) { switch (opt_params['compressionMethod']) { case Zlib.Zip.CompressionMethod.STORE: break; case Zlib.Zip.CompressionMethod.DEFLATE: crc32 = Zlib.CRC32.calc(input); input = this.deflateWithOption(input, opt_params); compressed = true; break; default: throw new Error('unknown compression method:' + opt_params['compressionMethod']); } } this.files.push({ buffer: input, option: opt_params, compressed: compressed, encrypted: false, size: size, crc32: crc32 }); }; /** * @param {(Array.<number>|Uint8Array)} password */ Zlib.Zip.prototype.setPassword = function (password) { this.password = password; }; Zlib.Zip.prototype.compress = function () { /** @type {Array.<{ * buffer: !(Array.<number>|Uint8Array), * option: Object, * compressed: boolean, * encrypted: boolean, * size: number, * crc32: number * }>} */ var files = this.files; /** @type {{ * buffer: !(Array.<number>|Uint8Array), * option: Object, * compressed: boolean, * encrypted: boolean, * size: number, * crc32: number * }} */ var file; /** @type {!(Array.<number>|Uint8Array)} */ var output; /** @type {number} */ var op1; /** @type {number} */ var op2; /** @type {number} */ var op3; /** @type {number} */ var localFileSize = 0; /** @type {number} */ var centralDirectorySize = 0; /** @type {number} */ var endOfCentralDirectorySize; /** @type {number} */ var offset; /** @type {number} */ var needVersion; /** @type {number} */ var flags; /** @type {Zlib.Zip.CompressionMethod} */ var compressionMethod; /** @type {Date} */ var date; /** @type {number} */ var crc32; /** @type {number} */ var size; /** @type {number} */ var plainSize; /** @type {number} */ var filenameLength; /** @type {number} */ var extraFieldLength; /** @type {number} */ var commentLength; /** @type {(Array.<number>|Uint8Array)} */ var filename; /** @type {(Array.<number>|Uint8Array)} */ var extraField; /** @type {(Array.<number>|Uint8Array)} */ var comment; /** @type {(Array.<number>|Uint8Array)} */ var buffer; /** @type {*} */ var tmp; /** @type {Array.<number>|Uint32Array|Object} */ var key; /** @type {number} */ var i; /** @type {number} */ var il; /** @type {number} */ var j; /** @type {number} */ var jl; // ファイルの圧縮 for (i = 0, il = files.length; i < il; ++i) { file = files[i]; filenameLength = file.option['filename'] ? file.option['filename'].length : 0; extraFieldLength = file.option['extraField'] ? file.option['extraField'].length : 0; commentLength = file.option['comment'] ? file.option['comment'].length : 0; // 圧縮されていなかったら圧縮 if (!file.compressed) { // 圧縮前に CRC32 の計算をしておく file.crc32 = Zlib.CRC32.calc(file.buffer); switch (file.option['compressionMethod']) { case Zlib.Zip.CompressionMethod.STORE: break; case Zlib.Zip.CompressionMethod.DEFLATE: file.buffer = this.deflateWithOption(file.buffer, file.option); file.compressed = true; break; default: throw new Error('unknown compression method:' + file.option['compressionMethod']); } } // encryption if (file.option['password'] !== void 0 || this.password !== void 0) { // init encryption key = this.createEncryptionKey(file.option['password'] || this.password); // add header buffer = file.buffer; { tmp = new Uint8Array(buffer.length + 12); tmp.set(buffer, 12); buffer = tmp; } for (j = 0; j < 12; ++j) { buffer[j] = this.encode(key, i === 11 ? file.crc32 & 0xff : Math.random() * 256 | 0); } // data encryption for (jl = buffer.length; j < jl; ++j) { buffer[j] = this.encode(key, buffer[j]); } file.buffer = buffer; } // 必要バッファサイズの計算 localFileSize += // local file header 30 + filenameLength + // file data file.buffer.length; centralDirectorySize += // file header 46 + filenameLength + commentLength; } // end of central directory endOfCentralDirectorySize = 22 + (this.comment ? this.comment.length : 0); output = new (Uint8Array )(localFileSize + centralDirectorySize + endOfCentralDirectorySize); op1 = 0; op2 = localFileSize; op3 = op2 + centralDirectorySize; // ファイルの圧縮 for (i = 0, il = files.length; i < il; ++i) { file = files[i]; filenameLength = file.option['filename'] ? file.option['filename'].length : 0; extraFieldLength = 0; // TODO commentLength = file.option['comment'] ? file.option['comment'].length : 0; //------------------------------------------------------------------------- // local file header & file header //------------------------------------------------------------------------- offset = op1; // signature // local file header output[op1++] = Zlib.Zip.LocalFileHeaderSignature[0]; output[op1++] = Zlib.Zip.LocalFileHeaderSignature[1]; output[op1++] = Zlib.Zip.LocalFileHeaderSignature[2]; output[op1++] = Zlib.Zip.LocalFileHeaderSignature[3]; // file header output[op2++] = Zlib.Zip.FileHeaderSignature[0]; output[op2++] = Zlib.Zip.FileHeaderSignature[1]; output[op2++] = Zlib.Zip.FileHeaderSignature[2]; output[op2++] = Zlib.Zip.FileHeaderSignature[3]; // compressor info needVersion = 20; output[op2++] = needVersion & 0xff; output[op2++] = /** @type {Zlib.Zip.OperatingSystem} */ file.option['os'] || Zlib.Zip.OperatingSystem.MSDOS; // need version output[op1++] = output[op2++] = needVersion & 0xff; output[op1++] = output[op2++] = needVersion >> 8 & 0xff; // general purpose bit flag flags = 0; if (file.option['password'] || this.password) { flags |= Zlib.Zip.Flags.ENCRYPT; } output[op1++] = output[op2++] = flags & 0xff; output[op1++] = output[op2++] = flags >> 8 & 0xff; // compression method compressionMethod = /** @type {Zlib.Zip.CompressionMethod} */ file.option['compressionMethod']; output[op1++] = output[op2++] = compressionMethod & 0xff; output[op1++] = output[op2++] = compressionMethod >> 8 & 0xff; // date date = /** @type {(Date|undefined)} */ file.option['date'] || new Date(); output[op1++] = output[op2++] = (date.getMinutes() & 0x7) << 5 | (date.getSeconds() / 2 | 0); output[op1++] = output[op2++] = date.getHours() << 3 | date.getMinutes() >> 3; // output[op1++] = output[op2++] = (date.getMonth() + 1 & 0x7) << 5 | date.getDate(); output[op1++] = output[op2++] = (date.getFullYear() - 1980 & 0x7f) << 1 | date.getMonth() + 1 >> 3; // CRC-32 crc32 = file.crc32; output[op1++] = output[op2++] = crc32 & 0xff; output[op1++] = output[op2++] = crc32 >> 8 & 0xff; output[op1++] = output[op2++] = crc32 >> 16 & 0xff; output[op1++] = output[op2++] = crc32 >> 24 & 0xff; // compressed size size = file.buffer.length; output[op1++] = output[op2++] = size & 0xff; output[op1++] = output[op2++] = size >> 8 & 0xff; output[op1++] = output[op2++] = size >> 16 & 0xff; output[op1++] = output[op2++] = size >> 24 & 0xff; // uncompressed size plainSize = file.size; output[op1++] = output[op2++] = plainSize & 0xff; output[op1++] = output[op2++] = plainSize >> 8 & 0xff; output[op1++] = output[op2++] = plainSize >> 16 & 0xff; output[op1++] = output[op2++] = plainSize >> 24 & 0xff; // filename length output[op1++] = output[op2++] = filenameLength & 0xff; output[op1++] = output[op2++] = filenameLength >> 8 & 0xff; // extra field length output[op1++] = output[op2++] = extraFieldLength & 0xff; output[op1++] = output[op2++] = extraFieldLength >> 8 & 0xff; // file comment length output[op2++] = commentLength & 0xff; output[op2++] = commentLength >> 8 & 0xff; // disk number start output[op2++] = 0; output[op2++] = 0; // internal file attributes output[op2++] = 0; output[op2++] = 0; // external file attributes output[op2++] = 0; output[op2++] = 0; output[op2++] = 0; output[op2++] = 0; // relative offset of local header output[op2++] = offset & 0xff; output[op2++] = offset >> 8 & 0xff; output[op2++] = offset >> 16 & 0xff; output[op2++] = offset >> 24 & 0xff; // filename filename = file.option['filename']; if (filename) { { output.set(filename, op1); output.set(filename, op2); op1 += filenameLength; op2 += filenameLength; } } // extra field extraField = file.option['extraField']; if (extraField) { { output.set(extraField, op1); output.set(extraField, op2); op1 += extraFieldLength; op2 += extraFieldLength; } } // comment comment = file.option['comment']; if (comment) { { output.set(comment, op2); op2 += commentLength; } } //------------------------------------------------------------------------- // file data //------------------------------------------------------------------------- { output.set(file.buffer, op1); op1 += file.buffer.length; } } //------------------------------------------------------------------------- // end of central directory //------------------------------------------------------------------------- // signature output[op3++] = Zlib.Zip.CentralDirectorySignature[0]; output[op3++] = Zlib.Zip.CentralDirectorySignature[1]; output[op3++] = Zlib.Zip.CentralDirectorySignature[2]; output[op3++] = Zlib.Zip.CentralDirectorySignature[3]; // number of this disk output[op3++] = 0; output[op3++] = 0; // number of the disk with the start of the central directory output[op3++] = 0; output[op3++] = 0; // total number of entries in the central directory on this disk output[op3++] = il & 0xff; output[op3++] = il >> 8 & 0xff; // total number of entries in the central directory output[op3++] = il & 0xff; output[op3++] = il >> 8 & 0xff; // size of the central directory output[op3++] = centralDirectorySize & 0xff; output[op3++] = centralDirectorySize >> 8 & 0xff; output[op3++] = centralDirectorySize >> 16 & 0xff; output[op3++] = centralDirectorySize >> 24 & 0xff; // offset of start of central directory with respect to the starting disk number output[op3++] = localFileSize & 0xff; output[op3++] = localFileSize >> 8 & 0xff; output[op3++] = localFileSize >> 16 & 0xff; output[op3++] = localFileSize >> 24 & 0xff; // .ZIP file comment length commentLength = this.comment ? this.comment.length : 0; output[op3++] = commentLength & 0xff; output[op3++] = commentLength >> 8 & 0xff; // .ZIP file comment if (this.comment) { { output.set(this.comment, op3); op3 += commentLength; } } return output; }; /** * @param {!(Array.<number>|Uint8Array)} input * @param {Object=} opt_params options. * @return {!(Array.<number>|Uint8Array)} */ Zlib.Zip.prototype.deflateWithOption = function (input, opt_params) { /** @type {Zlib.RawDeflate} */ var deflator = new Zlib.RawDeflate(input, opt_params['deflateOption']); return deflator.compress(); }; /** * @param {(Array.<number>|Uint32Array)} key * @return {number} */ Zlib.Zip.prototype.getByte = function (key) { /** @type {number} */ var tmp = key[2] & 0xffff | 2; return tmp * (tmp ^ 1) >> 8 & 0xff; }; /** * @param {(Array.<number>|Uint32Array|Object)} key * @param {number} n * @return {number} */ Zlib.Zip.prototype.encode = function (key, n) { /** @type {number} */ var tmp = this.getByte( /** @type {(Array.<number>|Uint32Array)} */ key); this.updateKeys( /** @type {(Array.<number>|Uint32Array)} */ key, n); return tmp ^ n; }; /** * @param {(Array.<number>|Uint32Array)} key * @param {number} n */ Zlib.Zip.prototype.updateKeys = function (key, n) { key[0] = Zlib.CRC32.single(key[0], n); key[1] = (((key[1] + (key[0] & 0xff)) * 20173 >>> 0) * 6681 >>> 0) + 1 >>> 0; key[2] = Zlib.CRC32.single(key[2], key[1] >>> 24); }; /** * @param {(Array.<number>|Uint8Array)} password * @return {!(Array.<number>|Uint32Array|Object)} */ Zlib.Zip.prototype.createEncryptionKey = function (password) { /** @type {!(Array.<number>|Uint32Array)} */ var key = [305419896, 591751049, 878082192]; /** @type {number} */ var i; /** @type {number} */ var il; { key = new Uint32Array(key); } for (i = 0, il = password.length; i < il; ++i) { this.updateKeys(key, password[i] & 0xff); } return key; }; /** * build huffman table from length list. * @param {!(Array.<number>|Uint8Array)} lengths length list. * @return {!Array} huffman table. */ Zlib.Huffman.buildHuffmanTable = function (lengths) { /** @type {number} length list size. */ var listSize = lengths.length; /** @type {number} max code length for table size. */ var maxCodeLength = 0; /** @type {number} min code length for table size. */ var minCodeLength = Number.POSITIVE_INFINITY; /** @type {number} table size. */ var size; /** @type {!(Array|Uint8Array)} huffman code table. */ var table; /** @type {number} bit length. */ var bitLength; /** @type {number} huffman code. */ var code; /** * サイズが 2^maxlength 個のテーブルを埋めるためのスキップ長. * @type {number} skip length for table filling. */ var skip; /** @type {number} reversed code. */ var reversed; /** @type {number} reverse temp. */ var rtemp; /** @type {number} loop counter. */ var i; /** @type {number} loop limit. */ var il; /** @type {number} loop counter. */ var j; /** @type {number} table value. */ var value; // Math.max は遅いので最長の値は for-loop で取得する for (i = 0, il = listSize; i < il; ++i) { if (lengths[i] > maxCodeLength) { maxCodeLength = lengths[i]; } if (lengths[i] < minCodeLength) { minCodeLength = lengths[i]; } } size = 1 << maxCodeLength; table = new (Uint32Array )(size); // ビット長の短い順からハフマン符号を割り当てる for (bitLength = 1, code = 0, skip = 2; bitLength <= maxCodeLength;) { for (i = 0; i < listSize; ++i) { if (lengths[i] === bitLength) { // ビットオーダーが逆になるためビット長分並びを反転する for (reversed = 0, rtemp = code, j = 0; j < bitLength; ++j) { reversed = reversed << 1 | rtemp & 1; rtemp >>= 1; } // 最大ビット長をもとにテーブルを作るため、 // 最大ビット長以外では 0 / 1 どちらでも良い箇所ができる // そのどちらでも良い場所は同じ値で埋めることで // 本来のビット長以上のビット数取得しても問題が起こらないようにする value = bitLength << 16 | i; for (j = reversed; j < size; j += skip) { table[j] = value; } ++code; } } // 次のビット長へ ++bitLength; code <<= 1; skip <<= 1; } return [table, maxCodeLength, minCodeLength]; }; //----------------------------------------------------------------------------- /** @define {number} buffer block size. */ var ZLIB_RAW_INFLATE_BUFFER_SIZE = 0x8000; // [ 0x8000 >= ZLIB_BUFFER_BLOCK_SIZE ] //----------------------------------------------------------------------------- var buildHuffmanTable = Zlib.Huffman.buildHuffmanTable; /** * @constructor * @param {!(Uint8Array|Array.<number>)} input input buffer. * @param {Object} opt_params option parameter. * * opt_params は以下のプロパティを指定する事ができます。 * - index: input buffer の deflate コンテナの開始位置. * - blockSize: バッファのブロックサイズ. * - bufferType: Zlib.RawInflate.BufferType の値によってバッファの管理方法を指定する. * - resize: 確保したバッファが実際の大きさより大きかった場合に切り詰める. */ Zlib.RawInflate = function (input, opt_params) { /** @type {!(Array.<number>|Uint8Array)} inflated buffer */ this.buffer; /** @type {!Array.<(Array.<number>|Uint8Array)>} */ this.blocks = []; /** @type {number} block size. */ this.bufferSize = ZLIB_RAW_INFLATE_BUFFER_SIZE; /** @type {!number} total output buffer pointer. */ this.totalpos = 0; /** @type {!number} input buffer pointer. */ this.ip = 0; /** @type {!number} bit stream reader buffer. */ this.bitsbuf = 0; /** @type {!number} bit stream reader buffer size. */ this.bitsbuflen = 0; /** @type {!(Array.<number>|Uint8Array)} input buffer. */ this.input = new Uint8Array(input) ; /** @type {!(Uint8Array|Array.<number>)} output buffer. */ this.output; /** @type {!number} output buffer pointer. */ this.op; /** @type {boolean} is final block flag. */ this.bfinal = false; /** @type {Zlib.RawInflate.BufferType} buffer management. */ this.bufferType = Zlib.RawInflate.BufferType.ADAPTIVE; /** @type {boolean} resize flag for memory size optimization. */ this.resize = false; // option parameters if (opt_params || !(opt_params = {})) { if (opt_params['index']) { this.ip = opt_params['index']; } if (opt_params['bufferSize']) { this.bufferSize = opt_params['bufferSize']; } if (opt_params['bufferType']) { this.bufferType = opt_params['bufferType']; } if (opt_params['resize']) { this.resize = opt_params['resize']; } } // initialize switch (this.bufferType) { case Zlib.RawInflate.BufferType.BLOCK: this.op = Zlib.RawInflate.MaxBackwardLength; this.output = new (Uint8Array )(Zlib.RawInflate.MaxBackwardLength + this.bufferSize + Zlib.RawInflate.MaxCopyLength); break; case Zlib.RawInflate.BufferType.ADAPTIVE: this.op = 0; this.output = new (Uint8Array )(this.bufferSize); break; default: throw new Error('invalid inflate mode'); } }; /** * @enum {number} */ Zlib.RawInflate.BufferType = { BLOCK: 0, ADAPTIVE: 1 }; /** * decompress. * @return {!(Uint8Array|Array.<number>)} inflated buffer. */ Zlib.RawInflate.prototype.decompress = function () { while (!this.bfinal) { this.parseBlock(); } switch (this.bufferType) { case Zlib.RawInflate.BufferType.BLOCK: return this.concatBufferBlock(); case Zlib.RawInflate.BufferType.ADAPTIVE: return this.concatBufferDynamic(); default: throw new Error('invalid inflate mode'); } }; /** * @const * @type {number} max backward length for LZ77. */ Zlib.RawInflate.MaxBackwardLength = 32768; /** * @const * @type {number} max copy length for LZ77. */ Zlib.RawInflate.MaxCopyLength = 258; /** * huffman order * @const * @type {!(Array.<number>|Uint8Array)} */ Zlib.RawInflate.Order = function (table) { return new Uint16Array(table) ; }([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); /** * huffman length code table. * @const * @type {!(Array.<number>|Uint16Array)} */ Zlib.RawInflate.LengthCodeTable = function (table) { return new Uint16Array(table) ; }([0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000d, 0x000f, 0x0011, 0x0013, 0x0017, 0x001b, 0x001f, 0x0023, 0x002b, 0x0033, 0x003b, 0x0043, 0x0053, 0x0063, 0x0073, 0x0083, 0x00a3, 0x00c3, 0x00e3, 0x0102, 0x0102, 0x0102]); /** * huffman length extra-bits table. * @const * @type {!(Array.<number>|Uint8Array)} */ Zlib.RawInflate.LengthExtraTable = function (table) { return new Uint8Array(table) ; }([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0]); /** * huffman dist code table. * @const * @type {!(Array.<number>|Uint16Array)} */ Zlib.RawInflate.DistCodeTable = function (table) { return new Uint16Array(table) ; }([0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, 0x0011, 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, 0x0101, 0x0181, 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, 0x1001, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001]); /** * huffman dist extra-bits table. * @const * @type {!(Array.<number>|Uint8Array)} */ Zlib.RawInflate.DistExtraTable = function (table) { return new Uint8Array(table) ; }([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13]); /** * fixed huffman length code table * @const * @type {!Array} */ Zlib.RawInflate.FixedLiteralLengthTable = function (table) { return table; }(function () { var lengths = new (Uint8Array )(288); var i, il; for (i = 0, il = lengths.length; i < il; ++i) { lengths[i] = i <= 143 ? 8 : i <= 255 ? 9 : i <= 279 ? 7 : 8; } return buildHuffmanTable(lengths); }()); /** * fixed huffman distance code table * @const * @type {!Array} */ Zlib.RawInflate.FixedDistanceTable = function (table) { return table; }(function () { var lengths = new (Uint8Array )(30); var i, il; for (i = 0, il = lengths.length; i < il; ++i) { lengths[i] = 5; } return buildHuffmanTable(lengths); }()); /** * parse deflated block. */ Zlib.RawInflate.prototype.parseBlock = function () { /** @type {number} header */ var hdr = this.readBits(3); // BFINAL if (hdr & 0x1) { this.bfinal = true; } // BTYPE hdr >>>= 1; switch (hdr) { // uncompressed case 0: this.parseUncompressedBlock(); break; // fixed huffman case 1: this.parseFixedHuffmanBlock(); break; // dynamic huffman case 2: this.parseDynamicHuffmanBlock(); break; // reserved or other default: throw new Error('unknown BTYPE: ' + hdr); } }; /** * read inflate bits * @param {number} length bits length. * @return {number} read bits. */ Zlib.RawInflate.prototype.readBits = function (length) { var bitsbuf = this.bitsbuf; var bitsbuflen = this.bitsbuflen; var input = this.input; var ip = this.ip; /** @type {number} */ var inputLength = input.length; /** @type {number} input and output byte. */ var octet; // input byte if (ip + (length - bitsbuflen + 7 >> 3) >= inputLength) { throw new Error('input buffer is broken'); } // not enough buffer while (bitsbuflen < length) { bitsbuf |= input[ip++] << bitsbuflen; bitsbuflen += 8; } // output byte octet = bitsbuf & /* MASK */ (1 << length) - 1; bitsbuf >>>= length; bitsbuflen -= length; this.bitsbuf = bitsbuf; this.bitsbuflen = bitsbuflen; this.ip = ip; return octet; }; /** * read huffman code using table * @param {!(Array.<number>|Uint8Array|Uint16Array)} table huffman code table. * @return {number} huffman code. */ Zlib.RawInflate.prototype.readCodeByTable = function (table) { var bitsbuf = this.bitsbuf; var bitsbuflen = this.bitsbuflen; var input = this.input; var ip = this.ip; /** @type {number} */ var inputLength = input.length; /** @type {!(Array.<number>|Uint8Array)} huffman code table */ var codeTable = table[0]; /** @type {number} */ var maxCodeLength = table[1]; /** @type {number} code length & code (16bit, 16bit) */ var codeWithLength; /** @type {number} code bits length */ var codeLength; // not enough buffer while (bitsbuflen < maxCodeLength) { if (ip >= inputLength) { break; } bitsbuf |= input[ip++] << bitsbuflen; bitsbuflen += 8; } // read max length codeWithLength = codeTable[bitsbuf & (1 << maxCodeLength) - 1]; codeLength = codeWithLength >>> 16; if (codeLength > bitsbuflen) { throw new Error('invalid code length: ' + codeLength); } this.