diff --git a/microscript/ILibDuktape_CompressedStream.c b/microscript/ILibDuktape_CompressedStream.c index e40d878..779c051 100644 --- a/microscript/ILibDuktape_CompressedStream.c +++ b/microscript/ILibDuktape_CompressedStream.c @@ -35,6 +35,7 @@ typedef struct ILibDuktape_CompressorStream void *object; ILibDuktape_DuplexStream *ds; z_stream Z; + uint32_t crc; }ILibDuktape_CompressorStream; @@ -69,6 +70,7 @@ void ILibDuktape_deCompressor_Resume(ILibDuktape_DuplexStream *sender, void *use avail = sizeof(buffer) - cs->Z.avail_out; if (avail > 0) { + cs->crc = crc32(cs->crc, buffer, (unsigned int)avail); res = ILibDuktape_DuplexStream_WriteData(cs->ds, buffer, (int)avail); // [stream] if (res == 1) { @@ -113,7 +115,11 @@ void ILibDuktape_Compressor_End(ILibDuktape_DuplexStream *stream, void *user) cs->Z.next_out = (Bytef*)tmp; ignore_result(deflate(&(cs->Z), Z_FINISH)); avail = sizeof(tmp) - cs->Z.avail_out; - if (avail > 0) { ILibDuktape_DuplexStream_WriteData(cs->ds, tmp, (int)avail); } + if (avail > 0) + { + cs->crc = crc32(cs->crc, tmp, (unsigned int)avail); + ILibDuktape_DuplexStream_WriteData(cs->ds, tmp, (int)avail); + } } while (cs->Z.avail_out == 0); ILibDuktape_DuplexStream_WriteEnd(cs->ds); @@ -139,6 +145,7 @@ ILibTransport_DoneState ILibDuktape_Compressor_Write(ILibDuktape_DuplexStream *s avail = sizeof(tmp) - cs->Z.avail_out; if (avail > 0) { + cs->crc = crc32(cs->crc, tmp, (unsigned int)avail); ret = ILibDuktape_DuplexStream_WriteData(cs->ds, tmp, (int)avail); } } while (cs->Z.avail_out == 0); @@ -161,6 +168,13 @@ duk_ret_t ILibDuktape_CompressedStream_resume_newListener(duk_context *ctx) duk_pcall_method(ctx, 0); return(0); } +duk_ret_t ILibDuktape_CompressedStream_crc(duk_context *ctx) +{ + duk_push_this(ctx); + ILibDuktape_CompressorStream *cs = (ILibDuktape_CompressorStream*)Duktape_GetBufferProperty(ctx, -1, ILibDuktape_CompressorStream_ptr); + duk_push_uint(ctx, cs->crc); + return(1); +} duk_ret_t ILibDuktape_CompressedStream_compressor(duk_context *ctx) { @@ -175,6 +189,8 @@ duk_ret_t ILibDuktape_CompressedStream_compressor(duk_context *ctx) cs->Z.zfree = Z_NULL; cs->Z.opaque = Z_NULL; if (deflateInit(&(cs->Z), Z_DEFAULT_COMPRESSION) != Z_OK) { return(ILibDuktape_Error(ctx, "zlib error")); } + + ILibDuktape_CreateEventWithGetter(ctx, "crc", ILibDuktape_CompressedStream_crc); ILibDuktape_CreateFinalizer(ctx, ILibDuktape_Compressor_Finalizer); cs->ds->readableStream->paused = 1; duk_events_newListener2(ctx, -1, "data", ILibDuktape_CompressedStream_resume_newListener); @@ -198,6 +214,7 @@ ILibTransport_DoneState ILibDuktape_deCompressor_Write(ILibDuktape_DuplexStream avail = sizeof(tmp) - cs->Z.avail_out; if (avail > 0) { + cs->crc = crc32(cs->crc, tmp, (unsigned int)avail); ret = ILibDuktape_DuplexStream_WriteData(cs->ds, tmp, (int)avail); if (ret == 1) { @@ -245,6 +262,7 @@ void ILibDuktape_deCompressor_End(ILibDuktape_DuplexStream *stream, void *user) avail = sizeof(tmp) - cs->Z.avail_out; if (avail > 0) { + cs->crc = crc32(cs->crc, tmp, (unsigned int)avail); ILibDuktape_DuplexStream_WriteData(cs->ds, tmp, (int)avail); } } while (cs->Z.avail_out == 0); @@ -265,7 +283,6 @@ duk_ret_t ILibDuktape_deCompressor_Finalizer(duk_context *ctx) } return(0); } - duk_ret_t ILibDuktape_CompressedStream_decompressor(duk_context *ctx) { duk_push_object(ctx); // [compressed-stream] @@ -289,6 +306,7 @@ duk_ret_t ILibDuktape_CompressedStream_decompressor(duk_context *ctx) if (inflateInit(&(cs->Z)) != Z_OK) { return(ILibDuktape_Error(ctx, "zlib error")); } } + ILibDuktape_CreateEventWithGetter(ctx, "crc", ILibDuktape_CompressedStream_crc); ILibDuktape_CreateFinalizer(ctx, ILibDuktape_deCompressor_Finalizer); cs->ds->readableStream->paused = 1; duk_events_newListener2(ctx, -1, "data", ILibDuktape_CompressedStream_resume_newListener); diff --git a/microscript/ILibDuktape_Polyfills.c b/microscript/ILibDuktape_Polyfills.c index 6638a0f..0cbff55 100644 --- a/microscript/ILibDuktape_Polyfills.c +++ b/microscript/ILibDuktape_Polyfills.c @@ -51,8 +51,6 @@ limitations under the License. - - typedef enum ILibDuktape_Console_DestinationFlags { ILibDuktape_Console_DestinationFlags_DISABLED = 0, @@ -1439,6 +1437,11 @@ void ILibDuktape_Stream_ResumeSink(struct ILibDuktape_readableStream *sender, vo duk_swap_top(sender->ctx, -2); // [read][this] if (duk_pcall_method(sender->ctx, 0) != 0) { ILibDuktape_Process_UncaughtException(sender->ctx); duk_pop(sender->ctx); break; } // // [buffer] + if (duk_is_null_or_undefined(sender->ctx, -1)) + { + duk_pop(sender->ctx); + break; + } duk_push_heapptr(sender->ctx, sender->object); // [buffer][this] duk_swap_top(sender->ctx, -2); // [this][buffer] if (duk_has_prop_string(sender->ctx, -2, ILibDuktape_Stream_Buffer)) @@ -1480,6 +1483,7 @@ int ILibDuktape_Stream_UnshiftSink(struct ILibDuktape_readableStream *sender, in duk_ret_t ILibDuktape_Stream_Push(duk_context *ctx) { duk_push_this(ctx); // [stream] + ILibDuktape_readableStream *RS = (ILibDuktape_readableStream*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Stream_ReadablePtr); duk_size_t bufferLen; @@ -2264,6 +2268,10 @@ void ILibDuktape_Polyfills_JS_Init(duk_context *ctx) // identifer: Refer to modules/identifers.js duk_peval_string_noresult(ctx, "addCompressedModule('identifiers', Buffer.from('eJztG2tz47bxu34FjpOWco6mbGUy01pROn6fmpPtWravGVnjUCQk4Y4iWQK0rDj6790F+BZp++5Sn5MrZ2yJwL6wD2CxgFrfNvb9YBmy6UyQ9tb23zfbW+0t0vMEdcm+HwZ+aAnme43GW2ZTj1OHRJ5DQyJmlOwGlg0fcY9BrmjIAZa0zS3SRAAt7tI2Oo2lH5G5tSSeL0jEKRBgnEyYSwm9s2kgCPOI7c8Dl1meTcmCiZlkEpMwGz/HBPyxsADWAugA3iZ5KGKJRoPAMxMi2Gm1FouFaUkpTT+ctlwFxVtve/uHJ4PDTZC00bj0XMo5Cel/IhbCAMdLYgUgh22NQTrXWhA/JNY0pNAnfJRzETLBvKlBuD8RCyukDYdxEbJxJAoKSqSCkeYBQEWWR7TdAekNNLK3O+gNjMa73sWb08sL8m73/Hz35KJ3OCCn52T/9OSgd9E7PYG3I7J78jP5qXdyYBAK6gEm9C4IUXYQkKHqqGM2BpQWmE98JQwPqM0mzIYRedPImlIy9W9p6MFASEDDOeNoPA6iOQ2XzZmQhufrwzEb37YajUnk2QhAYFjznkM9AcTBAZq3lrvRuJdWANbwGpJbVJpsx1bVhw+bkOYraB/ejshvv5H4W7dL9BPfo3qpTd8g98ShLhU0bu6QlaS1aqxyArnMi+5uWE6kRB6UJddOuuR+1Ul7QipKLcAlonkwKXDsKE19wvUNk96BZflg6dlNvcWXvGW7FuctZ85azNE3UGYxC/0FaerS5QPXEqCXOXF8II3RMLNuKTno9whHlXPBbKCbDA3FAIFDJuUosg6p5TgsrOXdKRiBoRFiUlWGKNJGWWoIt3TyOiE0ZKMNk/EjiOPmxkZKL6OMDyh2mMGPKseBFJ7KT/gDePGmTfgKzteEgRb4qdGUeCZOlXOiEkxnlVJJ3EpSyxxmqI+Zz28cS1BdDUMUmjo1CLfUc/ywhJI01iPJ2XQNK26tQvOt0LnxrHleulxbLQqnIbPcMlLSWou2NqxC6wNo5YEVmysQg9B3IlvcRBH4dYpXbI2dAF3dnjHXybuZbLgBeBtmSxm01JY+q7fGzGvxmW6QoQ4fozhoJAIEgeNHAj5CgvNPp9jse00d7G4Bbjr3NG0V8IxLrNddYufcFYK6TJ95Jq4mKKMlSAtFbNlBxLyJT34jsOgERJv74LAEbahBG0aDBrT162tPJ/oOTJPEWnwgm0c7RL8nAbAS5Js2WenXHkxO4trTCkwXFhOH0N7cqFA0sM4cqKyELNokYqtFjqiwZ+T47JKgwH9o/WsuD2yW6FwnV8e7BFWbafqXRNOgZavLYbkVzW+2DFhuKNfAKLqh/QKqVhaYEG2odeTky7rbHfaD1Xn9mqFwClFiwaxjTIPI0MIdksf8C7++Vv80gwB+d/sfmrajGdoGgg/buPClwCNgs7pOja0/aGwRLkGEgsmneZP/c3B6YgZWyGmzxvqoRAK+CnZv3t3hgFYldxgISBohvej9CVxitiCbci3CBO5DjTtI498Tl3olrzC0b6sdog0O0QX4xCdkhHc16LetAKWW3zn7larGjHTqNyDgPHY4pPkeaL7/wVY032d+hmDD9yND+B8gdzPAiwBBdamm4fbI+ECXhiY9kE2a8AJt3a7mUG6HTIqjIcFENB6NQZEJentktKVP5FHjmVnLxvYEJByuxJDjrkQADImjaIJuMgaxdDHR+O0VgGAWKUFexfBZlN1DhO0rSPi2kwSdAX99xCg3DkCwfNtKMzA622l0xmwNyc/AcaA8v2OwchVbNw69hWScf27MqgTXLObEubdOHkrm1WrtTeRby/xL1OKBAEYUQiQqAGjMp+sLBvnCgt8s5sy+gd1M5AreBNnzSbv0emCdDclUPqxfh5kWERK8CQFVmGyNEjAjD8MMBJP/QKKsXflafkOAwgC1YZJc4F6qyaBlG0KF/KDYmBB0UzHrEAzmUmKNZPzx+9wWQipOMkrFZOtipsxARoDb6qCwwBCHl+MHr3VJNybBcfAA1CjxhAJMEQMfkBXBCzjoY+uUOgXccuqMT5xlA0nzBOIhQ1B6NYOIz5rQG5NaFVxFwShXWfeVus1dvIVL4HZA66tOYRunHAAmRR5/zVo6n7BYxU0m9W6HOnJlmA+/xjVisORA9Lv29fViTOfwH/wbEeW6hi/wReb0+DmlAj9aV7tvLw+fecnLTztZjKCKqnLALO5ykSdXNdxfSrS13SU04ryCfTln7+adXdloKJerLblHlF+3R4lzJN4x1HPGl/NfElnrneX9WsxEPwfPtDg9yG3aapFzm5wEvW950cSywVFp+AT8bLeTEBj093qnA/y7yjY9mUWexfP2dgeHe6e75wd/Dvcj/2v/qzVycdOdmPhMZUAPukd57526h2w6iebjR/yrvAv/aAdd248nFL6cX+4PEtX93y8/xy/XSiaJaS8veweJU5QzOCBUSt+e2fr9w/7p+c/7b3pn+Pa2N7iQ9j86Pe/vXuzsD66+oBPEmjbj5MKc07kfYnZWmcGW5Xt+XZ4O8P/x4QtWoc9loeupKoQIeHYtnu2eX8gTmJfvkLAHFEwd2rxYp9w/u8wrcu+8d3j0cjVqB9HLVeXZ7sUb/HzHvO/aN1cwb/v7vidC33Vh2c9C/wRyE2M/CkOY19/4IfsVgCz3nHLfjWS1Iu6DNV8wO9/zcg0zfcmGwVKhE7Jb+gfydCnvR88brRbpeZDBCnkGgEkwTynn8ggzqTHHtZQ0N8KUahqfdkCWVLJw9SllAWQYY49M9HJURh1rVW54GD07Ty6NLilpH6iyW+UYS6W5qqE6t+VRKrWXB/oIaTWUexKXLncqKA6d25EZ9xtEFjNrwWSvQbC4WQuDnak3xepR5cmyrHZm6tJMiuU4VHO+GKlqkfGY48KPqvqkPj63bP/xik+uH6s+JHeKL533oyeBl3MMoTM/pFOy6bTJpk16p2fxDYLDuwB8U7lkcm4ld3SbzEnPBLvkWk/OAr5pG1h7M4iGJ0vJwQQ2qSOlp9alyybPtsAPHhp+DfrPevOb+C9gDVVW+OrtMc9VQr6AFVRt5qu3Qlxh+iIGUJy/dgtkvVj+eVZD5AtRf0478CW3hUs2Za4yc2iA2Y45Di0P5mFJ4NM0l0ulHrmK83gdryrFavAFgzQs3e8kVxOT/Mq2OCW6PPbVd9LkdA7mdCkYIvBDIU/VyM3p+D21Re9ghxTKkAaZUrGzfiGT5M5CxyG1PnRy/Ba4nf0sfhWnhA9ydKwQUD6L5VqSWsPQoRMLdlQPspIEM7/M3yC99HgUICR1SBLQ8q5oBbtVo0jbZPzAtz9QjIiUetKW5tS4xyr7A3nVTdwg3mFJN5pYLld7pk84OH054atlF+84dSctexr6UZBc9Snc9Nk8wu/ZjLmdzJhYHNBa8QUaNWPiBRqpWm3jXs2k2rbWWX3UPCrVvKaRV/IuNBi4s27hPUsIGi7P/AXFq+wFS8d9p7A6WOBAFdsoaVHFvXZqwM5sp7rmzyV/r59GEs7Zdvlpl5sDHNoNhoG7zB+U4JNutOWZS0z5sSsP63efa+8j53nLW8kxiyGT5aGWWAZUr7ifLG8fx+rXN9YkWJcptj9evAgj2qnsL2k5eVaN+rdKw5TnW3xQh8f9vE1ujqkHWwq7b4V8ZrllzSMCXhlHOx73zX1gJOiVBXuQMQT7drsCHELDo+537TzGiSXYLT0L/btlU/8pBjAdd41fghzj9amY+U5TP6ZCVehkAAxAoIiXUdHeKXoVQlMOZMO8gv0TxNrW4w6kMMDue9FkgpPpcHuEqNvtv5G//pXU9La///738IWPNvjacpdY5PNn75TRp83iMIk/ZQ5f40LDsIoLNv+OXLIVI5hzMMjmlIwhpqsvhaZLBXjHydGP7fTiIbnW0I7XeBFw/Yp2kWl5SUgevOBYnRDGi4NapROXqXeKytJbxbJy1S8uJVf9h1cP9UMb5I9qhoQmvWwOwcec+CohhEby3YRJNt4tl5cYtRJlaGugRfDMz6/6+NMsg/Q82yx5uwL412H/srLj37QcHrGaaoOwYjKuXBorYAu/NVHqKexjs0tI1Zp5FOGT9bOuBtU+oBbeXXo5KsrXWpRT1ZdiuqWBV8dKLRfcjz3goQ8h1NqBhSKy3D2/nB4Vukkf9pbMo8+v9fp9ASpTpQ+o9lc4f5RUU/jxWUk/yclM/Q3WskYTDHlZRlgwN71jYtaMDUr0R6+3fqSm1n8QlilDjjbzHZznss1Up25mbTRaLZJeSgREDKTNH3MXElOAtHaoQPJ3unIwSXlLAa1dLJSQ+fJ8eu1v88f4nhVeKcJCUis5O8hw0iJyDqtQ105QFeCml1S7VWt1MTwjn40wI58fZkp+Xh57qbaXw0/G3fgvUfbXsg==', 'base64'));"); + // zip-reader, refer to modules/zip-reader.js + duk_peval_string_noresult(ctx, "addCompressedModule('zip-reader', Buffer.from('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', 'base64'));"); + + #ifndef _NOHECI duk_peval_string_noresult(ctx, "addCompressedModule('heci', Buffer.from('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', 'base64'));"); #endif diff --git a/modules/zip-reader.js b/modules/zip-reader.js new file mode 100644 index 0000000..4de07a5 --- /dev/null +++ b/modules/zip-reader.js @@ -0,0 +1,287 @@ +/* +Copyright 2020 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +var EOCDR = 101010256; +var CDR = 33639248; +var LFR = 67324752; + +var promise = require('promise'); +var duplex = require('stream').Duplex; + +function checkFolderPath(dest) +{ + if (process.platform == 'win32') { dest = dest.split('/').join('\\'); } + var tokens = dest.split(process.platform == 'win32' ? '\\' : '/'); + + var base = tokens.shift(); + while(tokens.length > 1) + { + base += ((process.platform == 'win32' ? '\\' : '/') + tokens.shift()); + if(!require('fs').existsSync(base)) + { + require('fs').mkdirSync(base); + } + } +} +function extractNext(p) +{ + if (p.pending.length == 0) { p._res(); return; } + var next = p.pending.pop(); + var dest = p.baseFolder + (process.platform == 'win32' ? '\\' : '/') + next; + if (process.platform == 'win32') { dest = dest.split('/').join('\\'); } + console.info1('Extracting: ' + dest); + try + { + checkFolderPath(dest); + } + catch(e) + { + p._rej(e); + return; + } + + p._stream = p.source.getStream(next); + p._output = require('fs').createWriteStream(dest, { flags: 'wb' }); + p._output.name = next; + p._output.promise = p; + p._output.on('close', function () + { + if (this.promise._stream.crc != this.promise.source.crc(this.name)) + { + this.promise._rej('CRC Check failed'); + return; + } + extractNext(this.promise); + }); + p._stream.pipe(p._output); +} + +function zippedObject(table) +{ + this._ObjectID = 'zip-reader.zippedObject'; + this._table = table; + Object.defineProperty(this, 'files', { + get: function () + { + var ret = []; + var i; + for(i in this._table) + { + ret.push(this._table[i].name); + } + return (ret); + } + }); + this.crc = function crc(name) + { + return (this._table[name].crc); + }; + this.getStream = function getStream(name) + { + var info = this._table[name]; + if (!info) { throw ('not found'); } + + var ret; + + if (info.compression == 0) + { + console.info1('No Compression!'); + ret = new duplex( + { + write: function (chunk, flush) + { + console.info1('Pass/Thru: ' + chunk.length + ' bytes'); + this.crc = crc32(chunk, this.crc); + if(this._pushOK) + { + this._pushOK = this.push(chunk); + if (this._pushOK) + { + flush(); + this._flush = null; + } + else + { + this._flush = flush; + } + } + else + { + this._pendingData.push(chunk); + this._flush = flush; + } + }, + final: function (flush) + { + if (this._pushOK) + { + this.push(null); + flush(); + } + else + { + this._ended = true; + } + }, + read: function (size) + { + this._pushOK = true; + while (this._pendingData.length > 0 && (this._pushOK = this.push(this._pendingData.shift()))); + if (this._pushOK) + { + if(this._flush) + { + this._flush(); + this._flush = null; + } + else + { + this.emit('drain'); + } + } + + } + }); + ret.bufferMode = 1; + ret._pendingData = []; + ret._pushOK = false; + ret._ended = false; + ret._flush = null; + ret.crc = 0; + ret.pause(); + } + else + { + ret = require('compressed-stream').createDecompressor(1); + } + ret._info = info; + ret._readSink = function _readSink(err, bytesRead, buffer) + { + console.info2('read ' + bytesRead + ' bytes [ERR: ' + err + ']', _readSink.self._bytesLeft); + _readSink.self._bytesLeft -= bytesRead; + _readSink.self.write(buffer.slice(0, bytesRead), function () + { + // Done Writing, so read the next block + if(this._bytesLeft == 0) + { + console.info1('DONE Reading This record'); + // No More Data + this.end(); + } + else + { + // More Data To Read + console.info2('Requesting More Data: ' + this._bytesLeft, this._ObjectID); + require('fs').read(this._info.fd, { buffer: this._buffer, length: this._bytesLeft > 4096 ? 4096 : this._bytesLeft }, + this._readSink); + } + }); + }; + ret._readSink.self = ret; + ret._localHeaderSink = function _localHeaderSink(err, bytesRead, buffer) + { + console.info1(buffer.readUInt32LE(0) == LFR); + console.info1('General Purpose Flag: ' + buffer.readUInt16LE(6)); + console.info1('Compression Method: ' + buffer.readUInt16LE(8)); + console.info1('FileName Length: ' + buffer.readUInt16LE(26)); + console.info1('Extra Length: ' + buffer.readUInt16LE(28)); + _localHeaderSink.self._info.uncompressedCRC = buffer.readUInt32LE(14); + + console.info1('Requesting to read: ' + (_localHeaderSink.self._bytesLeft > 4096 ? 4096 : _localHeaderSink.self._bytesLeft) + ' bytes'); + + require('fs').read(_localHeaderSink.self._info.fd, + { + buffer: _localHeaderSink.self._buffer, + length: _localHeaderSink.self._bytesLeft > 4096 ? 4096 : _localHeaderSink.self._bytesLeft, + position: _localHeaderSink.self._info.offset + 30 + buffer.readUInt16LE(26) + buffer.readUInt16LE(28) + }, _localHeaderSink.self._readSink); + }; + ret._localHeaderSink.self = ret; + ret.once('drain', function () + { + this._bytesLeft = this._info.compressedSize; + this._buffer = Buffer.alloc(4096); + console.info1('Local Header @ ' + this._info.offset); + require('fs').read(this._info.fd, { buffer: Buffer.alloc(30), position: this._info.offset }, this._localHeaderSink); + }); + return (ret); + }; + this.extractAll = function extractAll(destFolder) + { + var i; + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + if (destFolder.endsWith(process.platform == 'win32' ? '\\' : '/')) { destFolder = destFolder.substring(0, destFolder.length - 1); } + ret.source = this; + ret.baseFolder = destFolder; + ret.pending = []; + for (i in this.files) + { + ret.pending.push(this.files[i]); + } + + extractNext(ret); + return (ret); + } +} + +function read(path) +{ + var ret = new promise(function(res,rej){this._res = res; this._rej = rej;}); + if (!require('fs').existsSync(path)) + { + ret._rej('File not found'); + return (ret); + } + ret._len = require('fs').statSync(path).size; + ret._fd = require('fs').openSync(path, require('fs').constants.O_RDONLY); + ret._cdr = function _cdr(err, bytesRead, buffer) + { + var table = {}; + while (buffer.length > 0) + { + if (buffer.readUInt32LE() != CDR) { _cdr.self._rej('Parse Error'); return; } + var nameLength = buffer.readUInt16LE(28); + var efLength = buffer.readUInt16LE(30); + var comLength = buffer.readUInt16LE(32); + var name = buffer.slice(46, 46 + nameLength).toString(); + + table[name] = { name: name, compressedSize: buffer.readUInt32LE(20), offset: buffer.readUInt32LE(42), fd: _cdr.self._fd, compression: buffer.readUInt16LE(10), crc: buffer.readUInt32LE(16) }; + buffer = buffer.slice(46 + nameLength + efLength + comLength); + } + + _cdr.self._res(new zippedObject(table)); + }; + ret._eocdr = function _eocdr(err, bytesRead, buffer) + { + var record; + var i; + + for (i = 20; i < buffer.length; ++i) + { + if ((record = buffer.slice(buffer.length - i)).readUInt32LE() == EOCDR) + { + require('fs').read(_eocdr.self._fd, { buffer: Buffer.alloc(record.readUInt32LE(12)), position: record.readUInt32LE(16) }, _eocdr.self._cdr); + break; + } + } + + }; + ret._cdr.self = ret; + ret._eocdr.self = ret; + require('fs').read(ret._fd, { buffer: Buffer.alloc(100), position: ret._len - 100 }, ret._eocdr); + return(ret); +} + +module.exports = { read: read }; \ No newline at end of file