From da650e2d634cf4a375e57948239f4c38088d2ddf Mon Sep 17 00:00:00 2001 From: Christian Zangl Date: Mon, 1 Dec 2014 23:39:21 +0100 Subject: [PATCH] add compression support (for zip & zlib) using https://github.com/imaya/zlib.js add zlibjs dependency, grunt task fix compData vs compdata bug --- .gitignore | 1 + Gruntfile.js | 10 +- package.json | 3 +- src/compression/jxg.js | 1262 -------------------------------------- src/packet/compressed.js | 60 +- 5 files changed, 35 insertions(+), 1301 deletions(-) delete mode 100644 src/compression/jxg.js diff --git a/.gitignore b/.gitignore index 01fd1cdc..e8b08ae8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ build/ .DS_Store node_modules/ npm* +src/compression/ test/lib/ dist/ openpgp.store/ diff --git a/Gruntfile.js b/Gruntfile.js index a6d76600..8415c571 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -118,6 +118,12 @@ module.exports = function(grunt) { cwd: 'node_modules/', src: ['mocha/mocha.css', 'mocha/mocha.js', 'chai/chai.js'], dest: 'test/lib/' + }, + zlib: { + expand: true, + cwd: 'node_modules/zlibjs/bin/', + src: ['rawdeflate.min.js','rawinflate.min.js','zlib.min.js'], + dest: 'src/compression/' } }, clean: ['dist/'], @@ -145,7 +151,7 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-connect'); grunt.registerTask('default', 'Build OpenPGP.js', function() { - grunt.task.run(['clean', 'browserify', 'replace', 'uglify', 'npm_pack']); + grunt.task.run(['clean', 'copy:zlib', 'browserify', 'replace', 'uglify', 'npm_pack']); //TODO jshint is not run because of too many discovered issues, once these are addressed it should autorun grunt.log.ok('Before Submitting a Pull Request please also run `grunt jshint`.'); }); @@ -182,5 +188,5 @@ module.exports = function(grunt) { }); // Test/Dev tasks - grunt.registerTask('test', ['copy', 'mochaTest', 'mocha_phantomjs']); + grunt.registerTask('test', ['copy:npm', 'mochaTest', 'mocha_phantomjs']); }; diff --git a/package.json b/package.json index 62d765b2..5728e514 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,8 @@ }, "dependencies": { "es6-promise": "^1.0.0", - "node-localstorage": "~0.3.4" + "node-localstorage": "~0.3.4", + "zlibjs": "^0.2.0" }, "repository": { "type": "git", diff --git a/src/compression/jxg.js b/src/compression/jxg.js deleted file mode 100644 index f23632ea..00000000 --- a/src/compression/jxg.js +++ /dev/null @@ -1,1262 +0,0 @@ -JXG = { - exists: (function(undefined) { - return function(v) { - return !(v === undefined || v === null); - }; - })() -}; -JXG.decompress = function(str) { - return unescape((new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(str))).unzip()[0][0]); -}; -/* - Copyright 2008-2012 - Matthias Ehmann, - Michael Gerhaeuser, - Carsten Miller, - Bianca Valentin, - Alfred Wassermann, - Peter Wilfahrt - - This file is part of JSXGraph. - - Dual licensed under the Apache License Version 2.0, or LGPL Version 3 licenses. - - You should have received a copy of the GNU Lesser General Public License - along with JSXCompressor. If not, see . - - You should have received a copy of the Apache License along with JSXCompressor. - If not, see . - -*/ - -/** - * @class Util class - * @classdesc Utilities for uncompressing and base64 decoding - * Class for gunzipping, unzipping and base64 decoding of files. - * It is used for reading GEONExT, Geogebra and Intergeo files. - * - * Only Huffman codes are decoded in gunzip. - * The code is based on the source code for gunzip.c by Pasi Ojala - * {@link http://www.cs.tut.fi/~albert/Dev/gunzip/gunzip.c} - * {@link http://www.cs.tut.fi/~albert} - */ -JXG.Util = {}; - -/** - * Unzip zip files - */ -JXG.Util.Unzip = function(barray) { - var outputArr = [], - output = "", - debug = false, - gpflags, - files = 0, - unzipped = [], - crc, - buf32k = new Array(32768), - bIdx = 0, - modeZIP = false, - - CRC, SIZE, - - bitReverse = [ - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff - ], - - cplens = [ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - ], - - cplext = [ - 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, 99, 99 - ], - /* 99==invalid */ - - cpdist = [ - 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 - ], - - cpdext = [ - 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 - ], - - border = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15], - - bA = barray, - - bytepos = 0, - bitpos = 0, - bb = 1, - bits = 0, - - NAMEMAX = 256, - - nameBuf = [], - - fileout; - - function readByte() { - bits += 8; - if (bytepos < bA.length) { - //if (debug) - // document.write(bytepos+": "+bA[bytepos]+"
"); - return bA[bytepos++]; - } else - return -1; - } - - function byteAlign() { - bb = 1; - } - - function readBit() { - var carry; - bits++; - carry = (bb & 1); - bb >>= 1; - if (bb === 0) { - bb = readByte(); - carry = (bb & 1); - bb = (bb >> 1) | 0x80; - } - return carry; - } - - function readBits(a) { - var res = 0, - i = a; - - while (i--) { - res = (res << 1) | readBit(); - } - if (a) { - res = bitReverse[res] >> (8 - a); - } - return res; - } - - function flushBuffer() { - //document.write('FLUSHBUFFER:'+buf32k); - bIdx = 0; - } - - function addBuffer(a) { - SIZE++; - //CRC=updcrc(a,crc); - buf32k[bIdx++] = a; - outputArr.push(String.fromCharCode(a)); - //output+=String.fromCharCode(a); - if (bIdx == 0x8000) { - //document.write('ADDBUFFER:'+buf32k); - bIdx = 0; - } - } - - function HufNode() { - this.b0 = 0; - this.b1 = 0; - this.jump = null; - this.jumppos = -1; - } - - var LITERALS = 288; - - var literalTree = new Array(LITERALS); - var distanceTree = new Array(32); - var treepos = 0; - var Places = null; - var Places2 = null; - - var impDistanceTree = new Array(64); - var impLengthTree = new Array(64); - - var len = 0; - var fpos = new Array(17); - fpos[0] = 0; - var flens; - var fmax; - - function IsPat() { - while (1) { - if (fpos[len] >= fmax) - return -1; - if (flens[fpos[len]] == len) - return fpos[len]++; - fpos[len]++; - } - } - - function Rec() { - var curplace = Places[treepos]; - var tmp; - if (debug) - document.write("
len:" + len + " treepos:" + treepos); - if (len == 17) { //war 17 - return -1; - } - treepos++; - len++; - - tmp = IsPat(); - if (debug) - document.write("
IsPat " + tmp); - if (tmp >= 0) { - curplace.b0 = tmp; /* leaf cell for 0-bit */ - if (debug) - document.write("
b0 " + curplace.b0); - } else { - /* Not a Leaf cell */ - curplace.b0 = 0x8000; - if (debug) - document.write("
b0 " + curplace.b0); - if (Rec()) - return -1; - } - tmp = IsPat(); - if (tmp >= 0) { - curplace.b1 = tmp; /* leaf cell for 1-bit */ - if (debug) - document.write("
b1 " + curplace.b1); - curplace.jump = null; /* Just for the display routine */ - } else { - /* Not a Leaf cell */ - curplace.b1 = 0x8000; - if (debug) - document.write("
b1 " + curplace.b1); - curplace.jump = Places[treepos]; - curplace.jumppos = treepos; - if (Rec()) - return -1; - } - len--; - return 0; - } - - function CreateTree(currentTree, numval, lengths, show) { - var i; - /* Create the Huffman decode tree/table */ - //document.write("
createtree
"); - if (debug) - document.write("currentTree " + currentTree + " numval " + numval + " lengths " + lengths + " show " + show); - Places = currentTree; - treepos = 0; - flens = lengths; - fmax = numval; - for (i = 0; i < 17; i++) - fpos[i] = 0; - len = 0; - if (Rec()) { - //fprintf(stderr, "invalid huffman tree\n"); - if (debug) - alert("invalid huffman tree\n"); - return -1; - } - if (debug) { - document.write('
Tree: ' + Places.length); - for (var a = 0; a < 32; a++) { - document.write("Places[" + a + "].b0=" + Places[a].b0 + "
"); - document.write("Places[" + a + "].b1=" + Places[a].b1 + "
"); - } - } - - /*if(show) { - var tmp; - for(tmp=currentTree;tmpjump?tmp->jump-currentTree:0,(tmp->jump?tmp->jump-currentTree:0)*6+0xcf0); - if(!(tmp.b0 & 0x8000)) { - //fprintf(stdout, " 0x%03x (%c)", tmp->b0,(tmp->b0<256 && isprint(tmp->b0))?tmp->b0:'�'); - } - if(!(tmp.b1 & 0x8000)) { - if((tmp.b0 & 0x8000)) - fprintf(stdout, " "); - fprintf(stdout, " 0x%03x (%c)", tmp->b1,(tmp->b1<256 && isprint(tmp->b1))?tmp->b1:'�'); - } - fprintf(stdout, "\n"); - } - }*/ - return 0; - } - - function DecodeValue(currentTree) { - var len, i, - xtreepos = 0, - X = currentTree[xtreepos], - b; - - /* decode one symbol of the data */ - while (1) { - b = readBit(); - if (debug) - document.write("b=" + b); - if (b) { - if (!(X.b1 & 0x8000)) { - if (debug) - document.write("ret1"); - return X.b1; /* If leaf node, return data */ - } - X = X.jump; - len = currentTree.length; - for (i = 0; i < len; i++) { - if (currentTree[i] === X) { - xtreepos = i; - break; - } - } - //xtreepos++; - } else { - if (!(X.b0 & 0x8000)) { - if (debug) - document.write("ret2"); - return X.b0; /* If leaf node, return data */ - } - //X++; //?????????????????? - xtreepos++; - X = currentTree[xtreepos]; - } - } - } - - function DeflateLoop() { - var last, c, type, i, j, len, dist; - - do { - /*if((last = readBit())){ - fprintf(errfp, "Last Block: "); - } else { - fprintf(errfp, "Not Last Block: "); - }*/ - last = readBit(); - type = readBits(2); - switch (type) { - case 0: - if (debug) - alert("Stored\n"); - break; - case 1: - if (debug) - alert("Fixed Huffman codes\n"); - break; - case 2: - if (debug) - alert("Dynamic Huffman codes\n"); - break; - case 3: - if (debug) - alert("Reserved block type!!\n"); - break; - default: - if (debug) - alert("Unexpected value %d!\n", type); - break; - } - - if (type === 0) { - var blockLen, cSum; - - // Stored - byteAlign(); - blockLen = readByte(); - blockLen |= (readByte() << 8); - - cSum = readByte(); - cSum |= (readByte() << 8); - - if (((blockLen ^ ~cSum) & 0xffff)) { - document.write("BlockLen checksum mismatch\n"); - } - while (blockLen--) { - c = readByte(); - addBuffer(c); - } - } else if (type == 1) { - /* Fixed Huffman tables -- fixed decode routine */ - while (1) { - /* - 256 0000000 0 - : : : - 279 0010111 23 - 0 00110000 48 - : : : - 143 10111111 191 - 280 11000000 192 - : : : - 287 11000111 199 - 144 110010000 400 - : : : - 255 111111111 511 - - Note the bit order! - */ - - j = (bitReverse[readBits(7)] >> 1); - if (j > 23) { - j = (j << 1) | readBit(); /* 48..255 */ - - if (j > 199) { /* 200..255 */ - j -= 128; /* 72..127 */ - j = (j << 1) | readBit(); /* 144..255 << */ - } else { /* 48..199 */ - j -= 48; /* 0..151 */ - if (j > 143) { - j = j + 136; /* 280..287 << */ - /* 0..143 << */ - } - } - } else { /* 0..23 */ - j += 256; /* 256..279 << */ - } - if (j < 256) { - addBuffer(j); - //document.write("out:"+String.fromCharCode(j)); - /*fprintf(errfp, "@%d %02x\n", SIZE, j);*/ - } else if (j == 256) { - /* EOF */ - break; - } else { - j -= 256 + 1; /* bytes + EOF */ - len = readBits(cplext[j]) + cplens[j]; - - j = bitReverse[readBits(5)] >> 3; - if (cpdext[j] > 8) { - dist = readBits(8); - dist |= (readBits(cpdext[j] - 8) << 8); - } else { - dist = readBits(cpdext[j]); - } - dist += cpdist[j]; - - /*fprintf(errfp, "@%d (l%02x,d%04x)\n", SIZE, len, dist);*/ - for (j = 0; j < len; j++) { - c = buf32k[(bIdx - dist) & 0x7fff]; - addBuffer(c); - } - } - } // while - } else if (type == 2) { - var n, literalCodes, distCodes, lenCodes; - var ll = new Array(288 + 32); // "static" just to preserve stack - - // Dynamic Huffman tables - - literalCodes = 257 + readBits(5); - distCodes = 1 + readBits(5); - lenCodes = 4 + readBits(4); - //document.write("
param: "+literalCodes+" "+distCodes+" "+lenCodes+"
"); - for (j = 0; j < 19; j++) { - ll[j] = 0; - } - - // Get the decode tree code lengths - - //document.write("
"); - for (j = 0; j < lenCodes; j++) { - ll[border[j]] = readBits(3); - //document.write(ll[border[j]]+" "); - } - //fprintf(errfp, "\n"); - //document.write('
ll:'+ll); - len = distanceTree.length; - for (i = 0; i < len; i++) - distanceTree[i] = new HufNode(); - if (CreateTree(distanceTree, 19, ll, 0)) { - flushBuffer(); - return 1; - } - if (debug) { - document.write("
distanceTree"); - for (var a = 0; a < distanceTree.length; a++) { - document.write("
" + distanceTree[a].b0 + " " + distanceTree[a].b1 + " " + distanceTree[a].jump + " " + - distanceTree[a].jumppos); - /*if (distanceTree[a].jumppos!=-1) - document.write(" "+distanceTree[a].jump.b0+" "+distanceTree[a].jump.b1); - */ - } - } - //document.write('
tree created'); - - //read in literal and distance code lengths - n = literalCodes + distCodes; - i = 0; - var z = -1; - if (debug) - document.write("
n=" + n + " bits: " + bits + "
"); - while (i < n) { - z++; - j = DecodeValue(distanceTree); - if (debug) - document.write("
" + z + " i:" + i + " decode: " + j + " bits " + bits + "
"); - if (j < 16) { // length of code in bits (0..15) - ll[i++] = j; - } else if (j == 16) { // repeat last length 3 to 6 times - var l; - j = 3 + readBits(2); - if (i + j > n) { - flushBuffer(); - return 1; - } - l = i ? ll[i - 1] : 0; - while (j--) { - ll[i++] = l; - } - } else { - if (j == 17) { // 3 to 10 zero length codes - j = 3 + readBits(3); - } else { // j == 18: 11 to 138 zero length codes - j = 11 + readBits(7); - } - if (i + j > n) { - flushBuffer(); - return 1; - } - while (j--) { - ll[i++] = 0; - } - } - } - /*for(j=0; jliteralTree"); - outer: while (1) { - j = DecodeValue(literalTree); - if (j >= 256) { // In C64: if carry set - j -= 256; - if (j === 0) { - // EOF - break; - } - j--; - len = readBits(cplext[j]) + cplens[j]; - - j = DecodeValue(distanceTree); - if (cpdext[j] > 8) { - dist = readBits(8); - dist |= (readBits(cpdext[j] - 8) << 8); - } else { - dist = readBits(cpdext[j]); - } - dist += cpdist[j]; - while (len--) { - if (bIdx - dist < 0) { - break outer; - } - c = buf32k[(bIdx - dist) & 0x7fff]; - addBuffer(c); - } - } else { - addBuffer(j); - } - } - } - } while (!last); - flushBuffer(); - - byteAlign(); - return 0; - } - - JXG.Util.Unzip.prototype.unzipFile = function(name) { - var i; - this.unzip(); - //alert(unzipped[0][1]); - for (i = 0; i < unzipped.length; i++) { - if (unzipped[i][1] == name) { - return unzipped[i][0]; - } - } - }; - - JXG.Util.Unzip.prototype.deflate = function() { - outputArr = []; - var tmp = []; - modeZIP = false; - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "DEFLATE"; - files++; - return unzipped; - }; - - JXG.Util.Unzip.prototype.unzip = function() { - //convertToByteArray(input); - if (debug) - alert(bA); - /*for (i=0;i"); - } - */ - //alert(bA); - nextFile(); - return unzipped; - }; - - function nextFile() { - if (debug) - alert("NEXTFILE"); - outputArr = []; - var tmp = []; - modeZIP = false; - tmp[0] = readByte(); - tmp[1] = readByte(); - if (debug) - alert("type: " + tmp[0] + " " + tmp[1]); - if (tmp[0] == parseInt("78", 16) && tmp[1] == parseInt("da", 16)) { //GZIP - if (debug) - alert("GEONExT-GZIP"); - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "geonext.gxt"; - files++; - } - if (tmp[0] == parseInt("78", 16) && tmp[1] == parseInt("9c", 16)) { //ZLIB - if (debug) - alert("ZLIB"); - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "ZLIB"; - files++; - } - if (tmp[0] == parseInt("1f", 16) && tmp[1] == parseInt("8b", 16)) { //GZIP - if (debug) - alert("GZIP"); - //DeflateLoop(); - skipdir(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "file"; - files++; - } - if (tmp[0] == parseInt("50", 16) && tmp[1] == parseInt("4b", 16)) { //ZIP - modeZIP = true; - tmp[2] = readByte(); - tmp[3] = readByte(); - if (tmp[2] == parseInt("3", 16) && tmp[3] == parseInt("4", 16)) { - //MODE_ZIP - tmp[0] = readByte(); - tmp[1] = readByte(); - if (debug) - alert("ZIP-Version: " + tmp[1] + " " + tmp[0] / 10 + "." + tmp[0] % 10); - - gpflags = readByte(); - gpflags |= (readByte() << 8); - if (debug) - alert("gpflags: " + gpflags); - - var method = readByte(); - method |= (readByte() << 8); - if (debug) - alert("method: " + method); - - readByte(); - readByte(); - readByte(); - readByte(); - - var crc = readByte(); - crc |= (readByte() << 8); - crc |= (readByte() << 16); - crc |= (readByte() << 24); - - var compSize = readByte(); - compSize |= (readByte() << 8); - compSize |= (readByte() << 16); - compSize |= (readByte() << 24); - - var size = readByte(); - size |= (readByte() << 8); - size |= (readByte() << 16); - size |= (readByte() << 24); - - if (debug) - alert("local CRC: " + crc + "\nlocal Size: " + size + "\nlocal CompSize: " + compSize); - - var filelen = readByte(); - filelen |= (readByte() << 8); - - var extralen = readByte(); - extralen |= (readByte() << 8); - - if (debug) - alert("filelen " + filelen); - i = 0; - nameBuf = []; - var c; - while (filelen--) { - c = readByte(); - if (c == "/" | c == ":") { - i = 0; - } else if (i < NAMEMAX - 1) - nameBuf[i++] = String.fromCharCode(c); - } - if (debug) - alert("nameBuf: " + nameBuf); - - //nameBuf[i] = "\0"; - if (!fileout) - fileout = nameBuf; - - var i = 0; - while (i < extralen) { - c = readByte(); - i++; - } - - CRC = 0xffffffff; - SIZE = 0; - - if (size === 0 && fileOut.charAt(fileout.length - 1) == "/") { - //skipdir - if (debug) - alert("skipdir"); - } - if (method == 8) { - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = nameBuf.join(''); - files++; - //return outputArr.join(''); - } - skipdir(); - } - } - } - - function skipdir() { - var crc, - tmp = [], - compSize, size, os, i, c; - - if ((gpflags & 8)) { - tmp[0] = readByte(); - tmp[1] = readByte(); - tmp[2] = readByte(); - tmp[3] = readByte(); - - if (tmp[0] == parseInt("50", 16) && - tmp[1] == parseInt("4b", 16) && - tmp[2] == parseInt("07", 16) && - tmp[3] == parseInt("08", 16)) { - crc = readByte(); - crc |= (readByte() << 8); - crc |= (readByte() << 16); - crc |= (readByte() << 24); - } else { - crc = tmp[0] | (tmp[1] << 8) | (tmp[2] << 16) | (tmp[3] << 24); - } - - compSize = readByte(); - compSize |= (readByte() << 8); - compSize |= (readByte() << 16); - compSize |= (readByte() << 24); - - size = readByte(); - size |= (readByte() << 8); - size |= (readByte() << 16); - size |= (readByte() << 24); - - if (debug) - alert("CRC:"); - } - - if (modeZIP) - nextFile(); - - tmp[0] = readByte(); - if (tmp[0] != 8) { - if (debug) - alert("Unknown compression method!"); - return 0; - } - - gpflags = readByte(); - if (debug) { - if ((gpflags & ~(parseInt("1f", 16)))) - alert("Unknown flags set!"); - } - - readByte(); - readByte(); - readByte(); - readByte(); - - readByte(); - os = readByte(); - - if ((gpflags & 4)) { - tmp[0] = readByte(); - tmp[2] = readByte(); - len = tmp[0] + 256 * tmp[1]; - if (debug) - alert("Extra field size: " + len); - for (i = 0; i < len; i++) - readByte(); - } - - if ((gpflags & 8)) { - i = 0; - nameBuf = []; - while (c = readByte()) { - if (c == "7" || c == ":") - i = 0; - if (i < NAMEMAX - 1) - nameBuf[i++] = c; - } - //nameBuf[i] = "\0"; - if (debug) - alert("original file name: " + nameBuf); - } - - if ((gpflags & 16)) { - while (c = readByte()) { - //FILE COMMENT - } - } - - if ((gpflags & 2)) { - readByte(); - readByte(); - } - - DeflateLoop(); - - crc = readByte(); - crc |= (readByte() << 8); - crc |= (readByte() << 16); - crc |= (readByte() << 24); - - size = readByte(); - size |= (readByte() << 8); - size |= (readByte() << 16); - size |= (readByte() << 24); - - if (modeZIP) - nextFile(); - - } - -}; - -/** - * Base64 encoding / decoding - * {@link http://www.webtoolkit.info/} - */ -JXG.Util.Base64 = { - - // private property - _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", - - // public method for encoding - encode: function(input) { - var output = [], - chr1, chr2, chr3, enc1, enc2, enc3, enc4, - i = 0; - - input = JXG.Util.Base64._utf8_encode(input); - - while (i < input.length) { - - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - output.push([this._keyStr.charAt(enc1), - this._keyStr.charAt(enc2), - this._keyStr.charAt(enc3), - this._keyStr.charAt(enc4) - ].join('')); - } - - return output.join(''); - }, - - // public method for decoding - decode: function(input, utf8) { - var output = [], - chr1, chr2, chr3, - enc1, enc2, enc3, enc4, - i = 0; - - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - while (i < input.length) { - - enc1 = this._keyStr.indexOf(input.charAt(i++)); - enc2 = this._keyStr.indexOf(input.charAt(i++)); - enc3 = this._keyStr.indexOf(input.charAt(i++)); - enc4 = this._keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output.push(String.fromCharCode(chr1)); - - if (enc3 != 64) { - output.push(String.fromCharCode(chr2)); - } - if (enc4 != 64) { - output.push(String.fromCharCode(chr3)); - } - } - - output = output.join(''); - - if (utf8) { - output = JXG.Util.Base64._utf8_decode(output); - } - return output; - - }, - - // private method for UTF-8 encoding - _utf8_encode: function(string) { - string = string.replace(/\r\n/g, "\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - - var c = string.charCodeAt(n); - - if (c < 128) { - utftext += String.fromCharCode(c); - } else if ((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // private method for UTF-8 decoding - _utf8_decode: function(utftext) { - var string = [], - i = 0, - c = 0, - c2 = 0, - c3 = 0; - - while (i < utftext.length) { - c = utftext.charCodeAt(i); - if (c < 128) { - string.push(String.fromCharCode(c)); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i + 1); - string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); - i += 2; - } else { - c2 = utftext.charCodeAt(i + 1); - c3 = utftext.charCodeAt(i + 2); - string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); - i += 3; - } - } - return string.join(''); - }, - - _destrip: function(stripped, wrap) { - var lines = [], - lineno, i, - destripped = []; - - if (wrap === null) - wrap = 76; - - stripped.replace(/ /g, ""); - lineno = stripped.length / wrap; - for (i = 0; i < lineno; i++) - lines[i] = stripped.substr(i * wrap, wrap); - if (lineno != stripped.length / wrap) - lines[lines.length] = stripped.substr(lineno * wrap, stripped.length - (lineno * wrap)); - - for (i = 0; i < lines.length; i++) - destripped.push(lines[i]); - return destripped.join('\n'); - }, - - decodeAsArray: function(input) { - var dec = this.decode(input), - ar = [], - i; - for (i = 0; i < dec.length; i++) { - ar[i] = dec.charCodeAt(i); - } - return ar; - }, - - decodeGEONExT: function(input) { - return decodeAsArray(destrip(input), false); - } -}; - -/** - * @private - */ -JXG.Util.asciiCharCodeAt = function(str, i) { - var c = str.charCodeAt(i); - if (c > 255) { - switch (c) { - case 8364: - c = 128; - break; - case 8218: - c = 130; - break; - case 402: - c = 131; - break; - case 8222: - c = 132; - break; - case 8230: - c = 133; - break; - case 8224: - c = 134; - break; - case 8225: - c = 135; - break; - case 710: - c = 136; - break; - case 8240: - c = 137; - break; - case 352: - c = 138; - break; - case 8249: - c = 139; - break; - case 338: - c = 140; - break; - case 381: - c = 142; - break; - case 8216: - c = 145; - break; - case 8217: - c = 146; - break; - case 8220: - c = 147; - break; - case 8221: - c = 148; - break; - case 8226: - c = 149; - break; - case 8211: - c = 150; - break; - case 8212: - c = 151; - break; - case 732: - c = 152; - break; - case 8482: - c = 153; - break; - case 353: - c = 154; - break; - case 8250: - c = 155; - break; - case 339: - c = 156; - break; - case 382: - c = 158; - break; - case 376: - c = 159; - break; - default: - break; - } - } - return c; -}; - -/** - * Decoding string into utf-8 - * @param {String} string to decode - * @return {String} utf8 decoded string - */ -JXG.Util.utf8Decode = function(utftext) { - var string = []; - var i = 0; - var c = 0, - c1 = 0, - c2 = 0, - c3; - if (!JXG.exists(utftext)) return ''; - - while (i < utftext.length) { - c = utftext.charCodeAt(i); - - if (c < 128) { - string.push(String.fromCharCode(c)); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i + 1); - string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); - i += 2; - } else { - c2 = utftext.charCodeAt(i + 1); - c3 = utftext.charCodeAt(i + 2); - string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); - i += 3; - } - } - return string.join(''); -}; - -/** - * Generate a random uuid. - * http://www.broofa.com - * mailto:robert@broofa.com - * - * Copyright (c) 2010 Robert Kieffer - * Dual licensed under the MIT and GPL licenses. - * - * EXAMPLES: - * >>> Math.uuid() - * "92329D39-6F5C-4520-ABFC-AAB64544E172" - */ -JXG.Util.genUUID = function() { - // Private array of chars to use - var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''), - uuid = new Array(36), - rnd = 0, - r; - - for (var i = 0; i < 36; i++) { - if (i == 8 || i == 13 || i == 18 || i == 23) { - uuid[i] = '-'; - } else if (i == 14) { - uuid[i] = '4'; - } else { - if (rnd <= 0x02) rnd = 0x2000000 + (Math.random() * 0x1000000) | 0; - r = rnd & 0xf; - rnd = rnd >> 4; - uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; - } - } - - return uuid.join(''); -}; - - -module.exports = JXG; diff --git a/src/packet/compressed.js b/src/packet/compressed.js index 2142395e..4eff99c2 100644 --- a/src/packet/compressed.js +++ b/src/packet/compressed.js @@ -21,17 +21,21 @@ * {@link http://tools.ietf.org/html/rfc4880#section-5.6|RFC4880 5.6}: The Compressed Data packet contains compressed data. Typically, * this packet is found as the contents of an encrypted packet, or following * a Signature or One-Pass Signature packet, and contains a literal data packet. - * @requires compression/jxg - * @requires encoding/base64 + * @requires compression/zlib + * @requires compression/rawinflate + * @requires compression/rawdeflate * @requires enums + * @requires util * @module packet/compressed */ module.exports = Compressed; var enums = require('../enums.js'), - JXG = require('../compression/jxg.js'), - base64 = require('../encoding/base64.js'); + util = require('../util.js'), + Zlib = require('../compression/zlib.min.js'), + RawInflate = require('../compression/rawinflate.min.js'), + RawDeflate = require('../compression/rawdeflate.min.js'); /** * @constructor @@ -51,7 +55,7 @@ function Compressed() { * Compression algorithm * @type {compression} */ - this.algorithm = 'uncompressed'; + this.algorithm = 'zip'; /** * Compressed packet data @@ -93,7 +97,7 @@ Compressed.prototype.write = function () { * read by read_packet */ Compressed.prototype.decompress = function () { - var decompressed, compdata, radix; + var decompressed; switch (this.algorithm) { case 'uncompressed': @@ -101,35 +105,13 @@ Compressed.prototype.decompress = function () { break; case 'zip': - compData = this.compressed; - - radix = base64.encode(compData).replace(/\n/g, ""); - // no header in this case, directly call deflate - var jxg_obj = new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(radix)); - - decompressed = unescape(jxg_obj.deflate()[0][0]); + var inflate = new RawInflate.Zlib.RawInflate(util.str2Uint8Array(this.compressed)); + decompressed = util.Uint8Array2str(inflate.decompress()); break; case 'zlib': - //RFC 1950. Bits 0-3 Compression Method - var compressionMethod = this.compressed.charCodeAt(0) % 0x10; - - //Bits 4-7 RFC 1950 are LZ77 Window. Generally this value is 7 == 32k window size. - // 2nd Byte in RFC 1950 is for "FLAGs" Allows for a Dictionary - // (how is this defined). Basic checksum, and compression level. - - if (compressionMethod == 8) { //CM 8 is for DEFLATE, RFC 1951 - // remove 4 bytes ADLER32 checksum from the end - compData = this.compressed.substring(0, this.compressed.length - 4); - radix = base64.encode(compData).replace(/\n/g, ""); - //TODO check ADLER32 checksum - decompressed = JXG.decompress(radix); - break; - - } else { - throw new Error("Compression algorithm ZLIB only supports " + - "DEFLATE compression method."); - } + var inflate = new Zlib.Zlib.Inflate(util.str2Uint8Array(this.compressed)); + decompressed = util.Uint8Array2str(inflate.decompress()); break; case 'bzip2': @@ -147,21 +129,27 @@ Compressed.prototype.decompress = function () { * Compress the packet data (member decompressedData) */ Compressed.prototype.compress = function () { + var uncompressed, deflate; + uncompressed = this.packets.write(); + switch (this.algorithm) { case 'uncompressed': // - Uncompressed - this.compressed = this.packets.write(); + this.compressed = uncompressed; break; case 'zip': // - ZIP [RFC1951] - throw new Error("Compression algorithm ZIP [RFC1951] is not implemented."); + deflate = new RawDeflate.Zlib.RawDeflate(util.str2Uint8Array(uncompressed)); + this.compressed = util.Uint8Array2str(deflate.compress()); + break; case 'zlib': // - ZLIB [RFC1950] - // TODO: need to implement this - throw new Error("Compression algorithm ZLIB [RFC1950] is not implemented."); + deflate = new Zlib.Zlib.Deflate(util.str2Uint8Array(uncompressed)); + this.compressed = util.Uint8Array2str(deflate.compress()); + break; case 'bzip2': // - BZip2 [BZ2]