1 /*--
  2  Copyright 2009-2010 by Stefan Rusterholz.
  3  All rights reserved.
  4  You can choose between MIT and BSD-3-Clause license. License file will be added later.
  5  --*/
  6 
  7 /**
  8  * See cc.Codec.GZip.gunzip.
  9  * @param {Array | String} data The bytestream to decompress
 10  * Constructor
 11  */
 12 cc.Codec.GZip = function Jacob__GZip(data) {
 13     this.data = data;
 14 
 15     this.debug = false;
 16     this.gpflags = undefined;
 17     this.files = 0;
 18     this.unzipped = [];
 19     this.buf32k = new Array(32768);
 20     this.bIdx = 0;
 21     this.modeZIP = false;
 22     this.bytepos = 0;
 23     this.bb = 1;
 24     this.bits = 0;
 25     this.nameBuf = [];
 26     this.fileout = undefined;
 27     this.literalTree = new Array(cc.Codec.GZip.LITERALS);
 28     this.distanceTree = new Array(32);
 29     this.treepos = 0;
 30     this.Places = null;
 31     this.len = 0;
 32     this.fpos = new Array(17);
 33     this.fpos[0] = 0;
 34     this.flens = undefined;
 35     this.fmax = undefined;
 36 };
 37 
 38 /**
 39  * Unzips the gzipped data of the 'data' argument.
 40  * @param string  The bytestream to decompress. Either an array of Integers between 0 and 255, or a String.
 41  * @return {String}
 42  */
 43 cc.Codec.GZip.gunzip = function (string) {
 44     if (string.constructor === Array) {
 45     } else if (string.constructor === String) {
 46     }
 47     var gzip = new cc.Codec.GZip(string);
 48     return gzip.gunzip()[0][0];
 49 };
 50 
 51 cc.Codec.GZip.HufNode = function () {
 52     this.b0 = 0;
 53     this.b1 = 0;
 54     this.jump = null;
 55     this.jumppos = -1;
 56 };
 57 
 58 /**
 59  * @constant
 60  * @type Number
 61  */
 62 cc.Codec.GZip.LITERALS = 288;
 63 /**
 64  * @constant
 65  * @type Number
 66  */
 67 cc.Codec.GZip.NAMEMAX = 256;
 68 
 69 cc.Codec.GZip.bitReverse = [
 70     0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
 71     0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
 72     0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
 73     0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
 74     0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
 75     0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
 76     0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
 77     0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
 78     0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
 79     0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
 80     0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
 81     0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
 82     0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
 83     0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
 84     0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
 85     0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
 86     0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
 87     0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
 88     0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
 89     0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
 90     0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
 91     0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
 92     0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
 93     0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
 94     0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
 95     0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
 96     0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
 97     0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
 98     0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
 99     0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
100     0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
101     0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
102 ];
103 cc.Codec.GZip.cplens = [
104     3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
105     35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
106 ];
107 cc.Codec.GZip.cplext = [
108     0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
109     3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99
110 ];
111 /* 99==invalid */
112 cc.Codec.GZip.cpdist = [
113     0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d,
114     0x0011, 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1,
115     0x0101, 0x0181, 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01,
116     0x1001, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001
117 ];
118 cc.Codec.GZip.cpdext = [
119     0, 0, 0, 0, 1, 1, 2, 2,
120     3, 3, 4, 4, 5, 5, 6, 6,
121     7, 7, 8, 8, 9, 9, 10, 10,
122     11, 11, 12, 12, 13, 13
123 ];
124 cc.Codec.GZip.border = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
125 
126 
127 /**
128  * gunzip
129  * @return {Array}
130  */
131 cc.Codec.GZip.prototype.gunzip = function () {
132     this.outputArr = [];
133 
134     //convertToByteArray(input);
135     //if (this.debug) alert(this.data);
136 
137     this.nextFile();
138     return this.unzipped;
139 };
140 
141 cc.Codec.GZip.prototype.readByte = function () {
142     this.bits += 8;
143     if (this.bytepos < this.data.length) {
144         //return this.data[this.bytepos++]; // Array
145         return this.data.charCodeAt(this.bytepos++);
146     } else {
147         return -1;
148     }
149 };
150 
151 cc.Codec.GZip.prototype.byteAlign = function () {
152     this.bb = 1;
153 };
154 
155 cc.Codec.GZip.prototype.readBit = function () {
156     var carry;
157     this.bits++;
158     carry = (this.bb & 1);
159     this.bb >>= 1;
160     if (this.bb == 0) {
161         this.bb = this.readByte();
162         carry = (this.bb & 1);
163         this.bb = (this.bb >> 1) | 0x80;
164     }
165     return carry;
166 };
167 
168 cc.Codec.GZip.prototype.readBits = function (a) {
169     var res = 0,
170         i = a;
171 
172     while (i--) res = (res << 1) | this.readBit();
173     if (a) res = cc.Codec.GZip.bitReverse[res] >> (8 - a);
174 
175     return res;
176 };
177 
178 cc.Codec.GZip.prototype.flushBuffer = function () {
179     this.bIdx = 0;
180 };
181 
182 cc.Codec.GZip.prototype.addBuffer = function (a) {
183     this.buf32k[this.bIdx++] = a;
184     this.outputArr.push(String.fromCharCode(a));
185     if (this.bIdx == 0x8000) this.bIdx = 0;
186 };
187 
188 cc.Codec.GZip.prototype.IsPat = function () {
189     while (1) {
190         if (this.fpos[this.len] >= this.fmax)       return -1;
191         if (this.flens[this.fpos[this.len]] == this.len) return this.fpos[this.len]++;
192         this.fpos[this.len]++;
193     }
194 };
195 
196 cc.Codec.GZip.prototype.Rec = function () {
197     var curplace = this.Places[this.treepos];
198     var tmp;
199     //if (this.debug) document.write("<br>len:"+this.len+" treepos:"+this.treepos);
200     if (this.len == 17) { //war 17
201         return -1;
202     }
203     this.treepos++;
204     this.len++;
205 
206     tmp = this.IsPat();
207     //if (this.debug) document.write("<br>IsPat "+tmp);
208     if (tmp >= 0) {
209         curplace.b0 = tmp;
210         /* leaf cell for 0-bit */
211         //if (this.debug) document.write("<br>b0 "+curplace.b0);
212     } else {
213         /* Not a Leaf cell */
214         curplace.b0 = 0x8000;
215         //if (this.debug) document.write("<br>b0 "+curplace.b0);
216         if (this.Rec()) return -1;
217     }
218     tmp = this.IsPat();
219     if (tmp >= 0) {
220         curplace.b1 = tmp;
221         /* leaf cell for 1-bit */
222         //if (this.debug) document.write("<br>b1 "+curplace.b1);
223         curplace.jump = null;
224         /* Just for the display routine */
225     } else {
226         /* Not a Leaf cell */
227         curplace.b1 = 0x8000;
228         //if (this.debug) document.write("<br>b1 "+curplace.b1);
229         curplace.jump = this.Places[this.treepos];
230         curplace.jumppos = this.treepos;
231         if (this.Rec()) return -1;
232     }
233     this.len--;
234     return 0;
235 };
236 
237 cc.Codec.GZip.prototype.CreateTree = function (currentTree, numval, lengths, show) {
238     var i;
239     /* Create the Huffman decode tree/table */
240     //if (this.debug) document.write("currentTree "+currentTree+" numval "+numval+" lengths "+lengths+" show "+show);
241     this.Places = currentTree;
242     this.treepos = 0;
243     this.flens = lengths;
244     this.fmax = numval;
245     for (i = 0; i < 17; i++) this.fpos[i] = 0;
246     this.len = 0;
247     if (this.Rec()) {
248         //if (this.debug) alert("invalid huffman tree\n");
249         return -1;
250     }
251     // if (this.debug) {
252     //   document.write('<br>Tree: '+this.Places.length);
253     //   for (var a=0;a<32;a++){
254     //     document.write("Places["+a+"].b0="+this.Places[a].b0+"<br>");
255     //     document.write("Places["+a+"].b1="+this.Places[a].b1+"<br>");
256     //   }
257     // }
258 
259     return 0;
260 };
261 
262 cc.Codec.GZip.prototype.DecodeValue = function (currentTree) {
263     var len, i,
264         xtreepos = 0,
265         X = currentTree[xtreepos],
266         b;
267 
268     /* decode one symbol of the data */
269     while (1) {
270         b = this.readBit();
271         // if (this.debug) document.write("b="+b);
272         if (b) {
273             if (!(X.b1 & 0x8000)) {
274                 // if (this.debug) document.write("ret1");
275                 return X.b1;
276                 /* If leaf node, return data */
277             }
278             X = X.jump;
279             len = currentTree.length;
280             for (i = 0; i < len; i++) {
281                 if (currentTree[i] === X) {
282                     xtreepos = i;
283                     break;
284                 }
285             }
286         } else {
287             if (!(X.b0 & 0x8000)) {
288                 // if (this.debug) document.write("ret2");
289                 return X.b0;
290                 /* If leaf node, return data */
291             }
292             xtreepos++;
293             X = currentTree[xtreepos];
294         }
295     }
296     // if (this.debug) document.write("ret3");
297 
298     return -1;
299 };
300 
301 cc.Codec.GZip.prototype.DeflateLoop = function () {
302     var last, c, type, i, len;
303     do {
304         last = this.readBit();
305         type = this.readBits(2);
306 
307         if (type == 0) {
308             var blockLen, cSum;
309 
310             // Stored
311             this.byteAlign();
312             blockLen = this.readByte();
313             blockLen |= (this.readByte() << 8);
314 
315             cSum = this.readByte();
316             cSum |= (this.readByte() << 8);
317 
318             if (((blockLen ^ ~cSum) & 0xffff)) {
319                 document.write("BlockLen checksum mismatch\n"); // FIXME: use throw
320             }
321             while (blockLen--) {
322                 c = this.readByte();
323                 this.addBuffer(c);
324             }
325         } else if (type == 1) {
326             var j;
327 
328             /* Fixed Huffman tables -- fixed decode routine */
329             while (1) {
330                 /*
331                  256    0000000        0
332                  :   :     :
333                  279    0010111        23
334                  0   00110000    48
335                  :    :      :
336                  143    10111111    191
337                  280 11000000    192
338                  :    :      :
339                  287 11000111    199
340                  144    110010000    400
341                  :    :       :
342                  255    111111111    511
343 
344                  Note the bit order!
345                  */
346                 j = (cc.Codec.GZip.bitReverse[this.readBits(7)] >> 1);
347                 if (j > 23) {
348                     j = (j << 1) | this.readBit();
349                     /* 48..255 */
350 
351                     if (j > 199) {              /* 200..255 */
352                         j -= 128;
353                         /*  72..127 */
354                         j = (j << 1) | this.readBit();
355                         /* 144..255 << */
356                     } else {                    /*  48..199 */
357                         j -= 48;
358                         /*   0..151 */
359                         if (j > 143) {
360                             j = j + 136;
361                             /* 280..287 << */
362                             /*   0..143 << */
363                         }
364                     }
365                 } else {                      /*   0..23 */
366                     j += 256;
367                     /* 256..279 << */
368                 }
369                 if (j < 256) {
370                     this.addBuffer(j);
371                 } else if (j == 256) {
372                     /* EOF */
373                     break; // FIXME: make this the loop-condition
374                 } else {
375                     var len, dist;
376 
377                     j -= 256 + 1;
378                     /* bytes + EOF */
379                     len = this.readBits(cc.Codec.GZip.cplext[j]) + cc.Codec.GZip.cplens[j];
380 
381                     j = cc.Codec.GZip.bitReverse[this.readBits(5)] >> 3;
382                     if (cc.Codec.GZip.cpdext[j] > 8) {
383                         dist = this.readBits(8);
384                         dist |= (this.readBits(cc.Codec.GZip.cpdext[j] - 8) << 8);
385                     } else {
386                         dist = this.readBits(cc.Codec.GZip.cpdext[j]);
387                     }
388                     dist += cc.Codec.GZip.cpdist[j];
389 
390                     for (j = 0; j < len; j++) {
391                         var c = this.buf32k[(this.bIdx - dist) & 0x7fff];
392                         this.addBuffer(c);
393                     }
394                 }
395             } // while
396 
397         } else if (type == 2) {
398             var j, n, literalCodes, distCodes, lenCodes;
399             var ll = new Array(288 + 32);    // "static" just to preserve stack
400 
401             // Dynamic Huffman tables
402 
403             literalCodes = 257 + this.readBits(5);
404             distCodes = 1 + this.readBits(5);
405             lenCodes = 4 + this.readBits(4);
406             for (j = 0; j < 19; j++) {
407                 ll[j] = 0;
408             }
409 
410             // Get the decode tree code lengths
411 
412             for (j = 0; j < lenCodes; j++) {
413                 ll[cc.Codec.GZip.border[j]] = this.readBits(3);
414             }
415             len = this.distanceTree.length;
416             for (i = 0; i < len; i++) this.distanceTree[i] = new cc.Codec.GZip.HufNode();
417             if (this.CreateTree(this.distanceTree, 19, ll, 0)) {
418                 this.flushBuffer();
419                 return 1;
420             }
421             // if (this.debug) {
422             //   document.write("<br>distanceTree");
423             //   for(var a=0;a<this.distanceTree.length;a++){
424             //     document.write("<br>"+this.distanceTree[a].b0+" "+this.distanceTree[a].b1+" "+this.distanceTree[a].jump+" "+this.distanceTree[a].jumppos);
425             //   }
426             // }
427 
428             //read in literal and distance code lengths
429             n = literalCodes + distCodes;
430             i = 0;
431             var z = -1;
432             // if (this.debug) document.write("<br>n="+n+" bits: "+this.bits+"<br>");
433             while (i < n) {
434                 z++;
435                 j = this.DecodeValue(this.distanceTree);
436                 // if (this.debug) document.write("<br>"+z+" i:"+i+" decode: "+j+"    bits "+this.bits+"<br>");
437                 if (j < 16) {    // length of code in bits (0..15)
438                     ll[i++] = j;
439                 } else if (j == 16) {    // repeat last length 3 to 6 times
440                     var l;
441                     j = 3 + this.readBits(2);
442                     if (i + j > n) {
443                         this.flushBuffer();
444                         return 1;
445                     }
446                     l = i ? ll[i - 1] : 0;
447                     while (j--) {
448                         ll[i++] = l;
449                     }
450                 } else {
451                     if (j == 17) {        // 3 to 10 zero length codes
452                         j = 3 + this.readBits(3);
453                     } else {        // j == 18: 11 to 138 zero length codes
454                         j = 11 + this.readBits(7);
455                     }
456                     if (i + j > n) {
457                         this.flushBuffer();
458                         return 1;
459                     }
460                     while (j--) {
461                         ll[i++] = 0;
462                     }
463                 }
464             } // while
465 
466             // Can overwrite tree decode tree as it is not used anymore
467             len = this.literalTree.length;
468             for (i = 0; i < len; i++)
469                 this.literalTree[i] = new cc.Codec.GZip.HufNode();
470             if (this.CreateTree(this.literalTree, literalCodes, ll, 0)) {
471                 this.flushBuffer();
472                 return 1;
473             }
474             len = this.literalTree.length;
475             for (i = 0; i < len; i++) this.distanceTree[i] = new cc.Codec.GZip.HufNode();
476             var ll2 = new Array();
477             for (i = literalCodes; i < ll.length; i++) ll2[i - literalCodes] = ll[i];
478             if (this.CreateTree(this.distanceTree, distCodes, ll2, 0)) {
479                 this.flushBuffer();
480                 return 1;
481             }
482             // if (this.debug) document.write("<br>literalTree");
483             while (1) {
484                 j = this.DecodeValue(this.literalTree);
485                 if (j >= 256) {        // In C64: if carry set
486                     var len, dist;
487                     j -= 256;
488                     if (j == 0) {
489                         // EOF
490                         break;
491                     }
492                     j--;
493                     len = this.readBits(cc.Codec.GZip.cplext[j]) + cc.Codec.GZip.cplens[j];
494 
495                     j = this.DecodeValue(this.distanceTree);
496                     if (cc.Codec.GZip.cpdext[j] > 8) {
497                         dist = this.readBits(8);
498                         dist |= (this.readBits(cc.Codec.GZip.cpdext[j] - 8) << 8);
499                     } else {
500                         dist = this.readBits(cc.Codec.GZip.cpdext[j]);
501                     }
502                     dist += cc.Codec.GZip.cpdist[j];
503                     while (len--) {
504                         var c = this.buf32k[(this.bIdx - dist) & 0x7fff];
505                         this.addBuffer(c);
506                     }
507                 } else {
508                     this.addBuffer(j);
509                 }
510             } // while
511         }
512     } while (!last);
513     this.flushBuffer();
514 
515     this.byteAlign();
516     return 0;
517 };
518 
519 cc.Codec.GZip.prototype.unzipFile = function (name) {
520     var i;
521     this.gunzip();
522     for (i = 0; i < this.unzipped.length; i++) {
523         if (this.unzipped[i][1] == name) {
524             return this.unzipped[i][0];
525         }
526     }
527 };
528 
529 cc.Codec.GZip.prototype.nextFile = function () {
530     // if (this.debug) alert("NEXTFILE");
531 
532     this.outputArr = [];
533     this.modeZIP = false;
534 
535     var tmp = [];
536     tmp[0] = this.readByte();
537     tmp[1] = this.readByte();
538     // if (this.debug) alert("type: "+tmp[0]+" "+tmp[1]);
539 
540     if (tmp[0] == 0x78 && tmp[1] == 0xda) { //GZIP
541         // if (this.debug) alert("GEONExT-GZIP");
542         this.DeflateLoop();
543         // if (this.debug) alert(this.outputArr.join(''));
544         this.unzipped[this.files] = [this.outputArr.join(''), "geonext.gxt"];
545         this.files++;
546     }
547     if (tmp[0] == 0x1f && tmp[1] == 0x8b) { //GZIP
548         // if (this.debug) alert("GZIP");
549         this.skipdir();
550         // if (this.debug) alert(this.outputArr.join(''));
551         this.unzipped[this.files] = [this.outputArr.join(''), "file"];
552         this.files++;
553     }
554     if (tmp[0] == 0x50 && tmp[1] == 0x4b) { //ZIP
555         this.modeZIP = true;
556         tmp[2] = this.readByte();
557         tmp[3] = this.readByte();
558         if (tmp[2] == 0x03 && tmp[3] == 0x04) {
559             //MODE_ZIP
560             tmp[0] = this.readByte();
561             tmp[1] = this.readByte();
562             // if (this.debug) alert("ZIP-Version: "+tmp[1]+" "+tmp[0]/10+"."+tmp[0]%10);
563 
564             this.gpflags = this.readByte();
565             this.gpflags |= (this.readByte() << 8);
566             // if (this.debug) alert("gpflags: "+this.gpflags);
567 
568             var method = this.readByte();
569             method |= (this.readByte() << 8);
570             // if (this.debug) alert("method: "+method);
571 
572             this.readByte();
573             this.readByte();
574             this.readByte();
575             this.readByte();
576 
577 //       var crc = this.readByte();
578 //       crc |= (this.readByte()<<8);
579 //       crc |= (this.readByte()<<16);
580 //       crc |= (this.readByte()<<24);
581 
582             var compSize = this.readByte();
583             compSize |= (this.readByte() << 8);
584             compSize |= (this.readByte() << 16);
585             compSize |= (this.readByte() << 24);
586 
587             var size = this.readByte();
588             size |= (this.readByte() << 8);
589             size |= (this.readByte() << 16);
590             size |= (this.readByte() << 24);
591 
592             // if (this.debug) alert("local CRC: "+crc+"\nlocal Size: "+size+"\nlocal CompSize: "+compSize);
593 
594             var filelen = this.readByte();
595             filelen |= (this.readByte() << 8);
596 
597             var extralen = this.readByte();
598             extralen |= (this.readByte() << 8);
599 
600             // if (this.debug) alert("filelen "+filelen);
601             i = 0;
602             this.nameBuf = [];
603             while (filelen--) {
604                 var c = this.readByte();
605                 if (c == "/" | c == ":") {
606                     i = 0;
607                 } else if (i < cc.Codec.GZip.NAMEMAX - 1) {
608                     this.nameBuf[i++] = String.fromCharCode(c);
609                 }
610             }
611             // if (this.debug) alert("nameBuf: "+this.nameBuf);
612 
613             if (!this.fileout) this.fileout = this.nameBuf;
614 
615             var i = 0;
616             while (i < extralen) {
617                 c = this.readByte();
618                 i++;
619             }
620 
621             // if (size = 0 && this.fileOut.charAt(this.fileout.length-1)=="/"){
622             //   //skipdir
623             //   // if (this.debug) alert("skipdir");
624             // }
625             if (method == 8) {
626                 this.DeflateLoop();
627                 // if (this.debug) alert(this.outputArr.join(''));
628                 this.unzipped[this.files] = [this.outputArr.join(''), this.nameBuf.join('')];
629                 this.files++;
630             }
631             this.skipdir();
632         }
633     }
634 };
635 
636 cc.Codec.GZip.prototype.skipdir = function () {
637     var tmp = [];
638     var compSize, size, os, i, c;
639 
640     if ((this.gpflags & 8)) {
641         tmp[0] = this.readByte();
642         tmp[1] = this.readByte();
643         tmp[2] = this.readByte();
644         tmp[3] = this.readByte();
645 
646 //     if (tmp[0] == 0x50 && tmp[1] == 0x4b && tmp[2] == 0x07 && tmp[3] == 0x08) {
647 //       crc = this.readByte();
648 //       crc |= (this.readByte()<<8);
649 //       crc |= (this.readByte()<<16);
650 //       crc |= (this.readByte()<<24);
651 //     } else {
652 //       crc = tmp[0] | (tmp[1]<<8) | (tmp[2]<<16) | (tmp[3]<<24);
653 //     }
654 
655         compSize = this.readByte();
656         compSize |= (this.readByte() << 8);
657         compSize |= (this.readByte() << 16);
658         compSize |= (this.readByte() << 24);
659 
660         size = this.readByte();
661         size |= (this.readByte() << 8);
662         size |= (this.readByte() << 16);
663         size |= (this.readByte() << 24);
664     }
665 
666     if (this.modeZIP) this.nextFile();
667 
668     tmp[0] = this.readByte();
669     if (tmp[0] != 8) {
670         // if (this.debug) alert("Unknown compression method!");
671         return 0;
672     }
673 
674     this.gpflags = this.readByte();
675     // if (this.debug && (this.gpflags & ~(0x1f))) alert("Unknown flags set!");
676 
677     this.readByte();
678     this.readByte();
679     this.readByte();
680     this.readByte();
681 
682     this.readByte();
683     os = this.readByte();
684 
685     if ((this.gpflags & 4)) {
686         tmp[0] = this.readByte();
687         tmp[2] = this.readByte();
688         this.len = tmp[0] + 256 * tmp[1];
689         // if (this.debug) alert("Extra field size: "+this.len);
690         for (i = 0; i < this.len; i++)
691             this.readByte();
692     }
693 
694     if ((this.gpflags & 8)) {
695         i = 0;
696         this.nameBuf = [];
697         while (c = this.readByte()) {
698             if (c == "7" || c == ":")
699                 i = 0;
700             if (i < cc.Codec.GZip.NAMEMAX - 1)
701                 this.nameBuf[i++] = c;
702         }
703         //this.nameBuf[i] = "\0";
704         // if (this.debug) alert("original file name: "+this.nameBuf);
705     }
706 
707     if ((this.gpflags & 16)) {
708         while (c = this.readByte()) { // FIXME: looks like they read to the end of the stream, should be doable more efficiently
709             //FILE COMMENT
710         }
711     }
712 
713     if ((this.gpflags & 2)) {
714         this.readByte();
715         this.readByte();
716     }
717 
718     this.DeflateLoop();
719 
720 //   crc = this.readByte();
721 //   crc |= (this.readByte()<<8);
722 //   crc |= (this.readByte()<<16);
723 //   crc |= (this.readByte()<<24);
724 
725     size = this.readByte();
726     size |= (this.readByte() << 8);
727     size |= (this.readByte() << 16);
728     size |= (this.readByte() << 24);
729 
730     if (this.modeZIP) this.nextFile();
731 };
732