react / wstein / node_modules / browserify / node_modules / browserify-zlib / node_modules / pako / lib / deflate.js
80540 views'use strict';123var zlib_deflate = require('./zlib/deflate.js');4var utils = require('./utils/common');5var strings = require('./utils/strings');6var msg = require('./zlib/messages');7var zstream = require('./zlib/zstream');89var toString = Object.prototype.toString;1011/* Public constants ==========================================================*/12/* ===========================================================================*/1314var Z_NO_FLUSH = 0;15var Z_FINISH = 4;1617var Z_OK = 0;18var Z_STREAM_END = 1;1920var Z_DEFAULT_COMPRESSION = -1;2122var Z_DEFAULT_STRATEGY = 0;2324var Z_DEFLATED = 8;2526/* ===========================================================================*/272829/**30* class Deflate31*32* Generic JS-style wrapper for zlib calls. If you don't need33* streaming behaviour - use more simple functions: [[deflate]],34* [[deflateRaw]] and [[gzip]].35**/3637/* internal38* Deflate.chunks -> Array39*40* Chunks of output data, if [[Deflate#onData]] not overriden.41**/4243/**44* Deflate.result -> Uint8Array|Array45*46* Compressed result, generated by default [[Deflate#onData]]47* and [[Deflate#onEnd]] handlers. Filled after you push last chunk48* (call [[Deflate#push]] with `Z_FINISH` / `true` param).49**/5051/**52* Deflate.err -> Number53*54* Error code after deflate finished. 0 (Z_OK) on success.55* You will not need it in real life, because deflate errors56* are possible only on wrong options or bad `onData` / `onEnd`57* custom handlers.58**/5960/**61* Deflate.msg -> String62*63* Error message, if [[Deflate.err]] != 064**/656667/**68* new Deflate(options)69* - options (Object): zlib deflate options.70*71* Creates new deflator instance with specified params. Throws exception72* on bad params. Supported options:73*74* - `level`75* - `windowBits`76* - `memLevel`77* - `strategy`78*79* [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)80* for more information on these.81*82* Additional options, for internal needs:83*84* - `chunkSize` - size of generated data chunks (16K by default)85* - `raw` (Boolean) - do raw deflate86* - `gzip` (Boolean) - create gzip wrapper87* - `to` (String) - if equal to 'string', then result will be "binary string"88* (each char code [0..255])89* - `header` (Object) - custom header for gzip90* - `text` (Boolean) - true if compressed data believed to be text91* - `time` (Number) - modification time, unix timestamp92* - `os` (Number) - operation system code93* - `extra` (Array) - array of bytes with extra data (max 65536)94* - `name` (String) - file name (binary string)95* - `comment` (String) - comment (binary string)96* - `hcrc` (Boolean) - true if header crc should be added97*98* ##### Example:99*100* ```javascript101* var pako = require('pako')102* , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])103* , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);104*105* var deflate = new pako.Deflate({ level: 3});106*107* deflate.push(chunk1, false);108* deflate.push(chunk2, true); // true -> last chunk109*110* if (deflate.err) { throw new Error(deflate.err); }111*112* console.log(deflate.result);113* ```114**/115var Deflate = function(options) {116117this.options = utils.assign({118level: Z_DEFAULT_COMPRESSION,119method: Z_DEFLATED,120chunkSize: 16384,121windowBits: 15,122memLevel: 8,123strategy: Z_DEFAULT_STRATEGY,124to: ''125}, options || {});126127var opt = this.options;128129if (opt.raw && (opt.windowBits > 0)) {130opt.windowBits = -opt.windowBits;131}132133else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) {134opt.windowBits += 16;135}136137this.err = 0; // error code, if happens (0 = Z_OK)138this.msg = ''; // error message139this.ended = false; // used to avoid multiple onEnd() calls140this.chunks = []; // chunks of compressed data141142this.strm = new zstream();143this.strm.avail_out = 0;144145var status = zlib_deflate.deflateInit2(146this.strm,147opt.level,148opt.method,149opt.windowBits,150opt.memLevel,151opt.strategy152);153154if (status !== Z_OK) {155throw new Error(msg[status]);156}157158if (opt.header) {159zlib_deflate.deflateSetHeader(this.strm, opt.header);160}161};162163/**164* Deflate#push(data[, mode]) -> Boolean165* - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be166* converted to utf8 byte sequence.167* - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.168* See constants. Skipped or `false` means Z_NO_FLUSH, `true` meansh Z_FINISH.169*170* Sends input data to deflate pipe, generating [[Deflate#onData]] calls with171* new compressed chunks. Returns `true` on success. The last data block must have172* mode Z_FINISH (or `true`). That flush internal pending buffers and call173* [[Deflate#onEnd]].174*175* On fail call [[Deflate#onEnd]] with error code and return false.176*177* We strongly recommend to use `Uint8Array` on input for best speed (output178* array format is detected automatically). Also, don't skip last param and always179* use the same type in your code (boolean or number). That will improve JS speed.180*181* For regular `Array`-s make sure all elements are [0..255].182*183* ##### Example184*185* ```javascript186* push(chunk, false); // push one of data chunks187* ...188* push(chunk, true); // push last chunk189* ```190**/191Deflate.prototype.push = function(data, mode) {192var strm = this.strm;193var chunkSize = this.options.chunkSize;194var status, _mode;195196if (this.ended) { return false; }197198_mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH);199200// Convert data if needed201if (typeof data === 'string') {202// If we need to compress text, change encoding to utf8.203strm.input = strings.string2buf(data);204} else if (toString.call(data) === '[object ArrayBuffer]') {205strm.input = new Uint8Array(data);206} else {207strm.input = data;208}209210strm.next_in = 0;211strm.avail_in = strm.input.length;212213do {214if (strm.avail_out === 0) {215strm.output = new utils.Buf8(chunkSize);216strm.next_out = 0;217strm.avail_out = chunkSize;218}219status = zlib_deflate.deflate(strm, _mode); /* no bad return value */220221if (status !== Z_STREAM_END && status !== Z_OK) {222this.onEnd(status);223this.ended = true;224return false;225}226if (strm.avail_out === 0 || (strm.avail_in === 0 && _mode === Z_FINISH)) {227if (this.options.to === 'string') {228this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out)));229} else {230this.onData(utils.shrinkBuf(strm.output, strm.next_out));231}232}233} while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END);234235// Finalize on the last chunk.236if (_mode === Z_FINISH) {237status = zlib_deflate.deflateEnd(this.strm);238this.onEnd(status);239this.ended = true;240return status === Z_OK;241}242243return true;244};245246247/**248* Deflate#onData(chunk) -> Void249* - chunk (Uint8Array|Array|String): ouput data. Type of array depends250* on js engine support. When string output requested, each chunk251* will be string.252*253* By default, stores data blocks in `chunks[]` property and glue254* those in `onEnd`. Override this handler, if you need another behaviour.255**/256Deflate.prototype.onData = function(chunk) {257this.chunks.push(chunk);258};259260261/**262* Deflate#onEnd(status) -> Void263* - status (Number): deflate status. 0 (Z_OK) on success,264* other if not.265*266* Called once after you tell deflate that input stream complete267* or error happenned. By default - join collected chunks,268* free memory and fill `results` / `err` properties.269**/270Deflate.prototype.onEnd = function(status) {271// On success - join272if (status === Z_OK) {273if (this.options.to === 'string') {274this.result = this.chunks.join('');275} else {276this.result = utils.flattenChunks(this.chunks);277}278}279this.chunks = [];280this.err = status;281this.msg = this.strm.msg;282};283284285/**286* deflate(data[, options]) -> Uint8Array|Array|String287* - data (Uint8Array|Array|String): input data to compress.288* - options (Object): zlib deflate options.289*290* Compress `data` with deflate alrorythm and `options`.291*292* Supported options are:293*294* - level295* - windowBits296* - memLevel297* - strategy298*299* [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)300* for more information on these.301*302* Sugar (options):303*304* - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify305* negative windowBits implicitly.306* - `to` (String) - if equal to 'string', then result will be "binary string"307* (each char code [0..255])308*309* ##### Example:310*311* ```javascript312* var pako = require('pako')313* , data = Uint8Array([1,2,3,4,5,6,7,8,9]);314*315* console.log(pako.deflate(data));316* ```317**/318function deflate(input, options) {319var deflator = new Deflate(options);320321deflator.push(input, true);322323// That will never happens, if you don't cheat with options :)324if (deflator.err) { throw deflator.msg; }325326return deflator.result;327}328329330/**331* deflateRaw(data[, options]) -> Uint8Array|Array|String332* - data (Uint8Array|Array|String): input data to compress.333* - options (Object): zlib deflate options.334*335* The same as [[deflate]], but creates raw data, without wrapper336* (header and adler32 crc).337**/338function deflateRaw(input, options) {339options = options || {};340options.raw = true;341return deflate(input, options);342}343344345/**346* gzip(data[, options]) -> Uint8Array|Array|String347* - data (Uint8Array|Array|String): input data to compress.348* - options (Object): zlib deflate options.349*350* The same as [[deflate]], but create gzip wrapper instead of351* deflate one.352**/353function gzip(input, options) {354options = options || {};355options.gzip = true;356return deflate(input, options);357}358359360exports.Deflate = Deflate;361exports.deflate = deflate;362exports.deflateRaw = deflateRaw;363exports.gzip = gzip;364365