gzip.js 23 KB

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