Return-Path: X-Original-To: apmail-corinthia-commits-archive@minotaur.apache.org Delivered-To: apmail-corinthia-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 6BDBE18AEF for ; Sat, 1 Aug 2015 11:02:59 +0000 (UTC) Received: (qmail 55462 invoked by uid 500); 1 Aug 2015 11:02:59 -0000 Delivered-To: apmail-corinthia-commits-archive@corinthia.apache.org Received: (qmail 55444 invoked by uid 500); 1 Aug 2015 11:02:59 -0000 Mailing-List: contact commits-help@corinthia.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@corinthia.incubator.apache.org Delivered-To: mailing list commits@corinthia.incubator.apache.org Received: (qmail 55435 invoked by uid 99); 1 Aug 2015 11:02:59 -0000 Received: from Unknown (HELO spamd3-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 01 Aug 2015 11:02:59 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd3-us-west.apache.org (ASF Mail Server at spamd3-us-west.apache.org) with ESMTP id E002B1971D5 for ; Sat, 1 Aug 2015 11:02:58 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd3-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 1.77 X-Spam-Level: * X-Spam-Status: No, score=1.77 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, T_RP_MATCHES_RCVD=-0.01] autolearn=disabled Received: from mx1-eu-west.apache.org ([10.40.0.8]) by localhost (spamd3-us-west.apache.org [10.40.0.10]) (amavisd-new, port 10024) with ESMTP id 36bIOXuC1Sc1 for ; Sat, 1 Aug 2015 11:02:56 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-eu-west.apache.org (ASF Mail Server at mx1-eu-west.apache.org) with SMTP id F0C0A2139E for ; Sat, 1 Aug 2015 11:02:54 +0000 (UTC) Received: (qmail 55331 invoked by uid 99); 1 Aug 2015 11:02:54 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 01 Aug 2015 11:02:54 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id EAEC7DFBD5; Sat, 1 Aug 2015 11:02:53 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jani@apache.org To: commits@corinthia.incubator.apache.org Date: Sat, 01 Aug 2015 11:02:54 -0000 Message-Id: <986cdd77b963405f82b74309a7b7ffa6@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [2/2] incubator-corinthia git commit: ready to test local header ready to test local header Project: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/commit/bc2f161a Tree: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/tree/bc2f161a Diff: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/diff/bc2f161a Branch: refs/heads/newZipExperiment Commit: bc2f161ad565502ff9deb84233df4ed203958a19 Parents: 2866238 Author: jani Authored: Sat Aug 1 13:02:38 2015 +0200 Committer: jani Committed: Sat Aug 1 13:02:38 2015 +0200 ---------------------------------------------------------------------- DocFormats/headers/DFPlatform.h | 6 + DocFormats/platform/src/Wrapper_zip.c | 211 +++++++++++++++++++++-------- 2 files changed, 162 insertions(+), 55 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/bc2f161a/DocFormats/headers/DFPlatform.h ---------------------------------------------------------------------- diff --git a/DocFormats/headers/DFPlatform.h b/DocFormats/headers/DFPlatform.h index 50881d6..27a9c81 100644 --- a/DocFormats/headers/DFPlatform.h +++ b/DocFormats/headers/DFPlatform.h @@ -77,6 +77,7 @@ typedef struct { int fileNameLength; // Length of filename char *fileName; // filename } DFextZipDirEntry; +typedef DFextZipDirEntry * DFextZipDirEntryP; typedef struct { FILE *zipFile; // file handle to zip file int zipFileCount; // number of entries in array @@ -88,6 +89,11 @@ typedef DFextZipHandle * DFextZipHandleP; DFextZipHandleP DFextZipOpen(const char *zipFilename); DFextZipHandleP DFextZipCreate(const char *zipFilename); +unsigned char *DFextZipReadFile(DFextZipHandleP zipHandle, DFextZipDirEntryP zipEntry); + + + + int DFextZipClose(DFextZipHandleP zipHandle); int DFextZipOpenNextFile(DFextZipHandleP zipHandle, http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/bc2f161a/DocFormats/platform/src/Wrapper_zip.c ---------------------------------------------------------------------- diff --git a/DocFormats/platform/src/Wrapper_zip.c b/DocFormats/platform/src/Wrapper_zip.c index 89d3b49..5fcadf3 100644 --- a/DocFormats/platform/src/Wrapper_zip.c +++ b/DocFormats/platform/src/Wrapper_zip.c @@ -28,7 +28,7 @@ typedef struct { uint16_t centralDirectoryDiskNumber; // NOT USED uint16_t numEntriesThisDisk; // NOT USED uint16_t numEntries; // Number of files in Zip - uint32_t centralDirectorySize; // Size of directory (we only have one) + uint32_t centralDirectorySize; // NOT USED uint32_t centralDirectoryOffset; // Offset of directory in file (fseek) uint16_t zipCommentLength; // NOT USED // Followed by .ZIP file comment (variable size) @@ -42,107 +42,132 @@ typedef struct { uint16_t versionMadeBy; // NOT USED uint16_t versionNeededToExtract; // NOT USED uint16_t generalPurposeBitFlag; // NOT USED - uint16_t compressionMethod; // Zip algorithm + uint16_t compressionMethod; // NOT USED uint16_t lastModFileTime; // NOT USED uint16_t lastModFileDate; // NOT USED uint32_t crc32; // NOT USED - uint32_t compressedSize; // File size on disk - uint32_t uncompressedSize; // Real file size - uint16_t fileNameLength; // Length of filename + uint32_t compressedSize; // NOT USED + uint32_t uncompressedSize; // NOT USED + uint16_t fileNameLength; // Only used to skip to next record uint16_t extraFieldLength; // Only used to skip to next record uint16_t fileCommentLength; // Only used to skip to next record uint16_t diskNumberStart; // NOT USED uint16_t internalFileAttributes; // NOT USED uint32_t externalFileAttributes; // NOT USED - uint32_t relativeOffsetOflocalHeader; // NOT USED + uint32_t relativeOffsetOflocalHeader; // offset to file header } ZipDirectoryRecord; #pragma pack() static const uint32_t ZipDirectoryRecord_signature = 0x02014B50; +#pragma pack(1) +typedef struct { + uint32_t signature; // 0x04034B50 + uint16_t versionNeededToExtract; // NOT USED + uint16_t generalPurposeBitFlag; // NOT USED + uint16_t compressionMethod; // flat file or zip compressed + uint16_t lastModFileTime; // NOT USED + uint16_t lastModFileDate; // NOT USED + uint32_t crc32; // NOT USED + uint32_t compressedSize; // size to read from file + uint32_t uncompressedSize; // size in memory + uint16_t fileNameLength; // Length of file name + uint16_t extraFieldLength; // NOT USED +} ZipFileHeader; +#pragma pack() +static const uint32_t ZipFileHeader_signature = 0x04034B50; + static int readDirectory(FILE *zipFile, DFextZipHandleP zipHandle) { - unsigned long fileSize, readBytes; - unsigned char workBuf[4096]; - ZipEndRecord *recEnd; - ZipDirectoryRecord *recDir; - DFextZipDirEntry *zipDirEntry; - int i, zipDirSize, zipDirOffset; - + unsigned long fileSize, readBytes; + unsigned char workBuf[4096]; + int i, zipOffset; - //***** Read EndRecord ***** + //***** Read EndRecord ***** // the EndRecord contains information, where the directory is located + // find end of file, and calculate size - if (fseek(zipFile, 0, SEEK_END)) - return -1; - fileSize = ftell(zipFile); - if ( fileSize <= sizeof(ZipEndRecord) ) + if (fseek(zipFile, 0, SEEK_END) + || (fileSize = ftell(zipFile)) <= sizeof(ZipEndRecord)) return -1; // Read size of workBuf of filesize from end of file to locate EndRecord readBytes = (fileSize < sizeof(workBuf)) ? fileSize : sizeof(workBuf); - if (fseek(zipFile, fileSize - readBytes, SEEK_SET)) - return -1; - if (fread(workBuf, 1, readBytes, zipFile) < readBytes) + if (fseek(zipFile, fileSize - readBytes, SEEK_SET) + || fread(workBuf, 1, readBytes, zipFile) < readBytes) return -1; // search for EndRecord signature for (i = readBytes - sizeof(ZipEndRecord); i >= 0; i--) { - recEnd = (ZipEndRecord *)(workBuf + i); + ZipEndRecord *recEnd = (ZipEndRecord *)(workBuf + i); // check if we have a signature - if (recEnd->signature == ZipEndRecord_signature) + if (recEnd->signature == ZipEndRecord_signature) { + // update zipHandle + zipOffset = recEnd->centralDirectoryOffset; + zipHandle->zipFileCount = recEnd->numEntries; + zipHandle->zipFileEntries = xmalloc(zipHandle->zipFileCount * sizeof(DFextZipDirEntry)); break; + } } if (i < 0) return -1; - // update zipHandle - zipDirSize = recEnd->centralDirectorySize; - zipDirOffset = recEnd->centralDirectoryOffset; - zipHandle->zipFileCount = recEnd->numEntries; - zipHandle->zipFileEntries = xmalloc(zipHandle->zipFileCount * sizeof(DFextZipDirEntry)); - //***** Read Directory ***** // Each file has a global and a local entry, read both in a loop - // Find directory - if (fseek(zipFile, zipDirOffset, SEEK_SET)) - return -1; // loop through all entries for (i = 0; i < zipHandle->zipFileCount; i++) { - // Read global directory entry - if (fread(workBuf, 1, sizeof(ZipDirectoryRecord), zipFile) < sizeof(ZipDirectoryRecord)) - return -1; - recDir = (ZipDirectoryRecord *)workBuf; + ZipDirectoryRecord *recDir = (ZipDirectoryRecord *)workBuf; - // verify signature - if (recDir->signature != ZipDirectoryRecord_signature) - return -1; - - // Save global information - zipDirEntry = zipHandle->zipFileEntries + (i * sizeof(zipDirEntry)); - zipDirEntry->compressedSize = recDir->compressedSize; - zipDirEntry->fileNameLength = recDir->fileNameLength; - zipDirEntry->uncompressedSize = recDir->uncompressedSize; - zipDirEntry->compressionMethod = recDir->compressionMethod; - zipDirEntry->offset = recDir->relativeOffsetOflocalHeader; - - // Add filename - zipDirEntry->fileName = xmalloc(zipDirEntry->fileNameLength + 1); - if (fread(zipDirEntry->fileName, 1, zipDirEntry->fileNameLength, zipFile) < (unsigned long)zipDirEntry->fileNameLength) - return -1; - zipDirEntry->fileName[zipDirEntry->fileNameLength] = '\0'; + // Find next directory entry, read it and verify signature + if (fseek(zipFile, zipOffset, SEEK_SET) + || fread(workBuf, 1, sizeof(ZipDirectoryRecord), zipFile) < sizeof(ZipDirectoryRecord) + || recDir->signature != ZipDirectoryRecord_signature) + return -1; - // Skip extra info + // Skip extra info and store pointer at next entry if (fseek(zipFile, recDir->extraFieldLength, SEEK_CUR) - || fseek(zipFile, recDir->fileCommentLength, SEEK_CUR)) + || fseek(zipFile, recDir->fileCommentLength, SEEK_CUR) + || fseek(zipFile, recDir->fileNameLength, SEEK_CUR)) return -1; + zipOffset = ftell(zipFile); + + + //***** Read File header ***** + // Each file starts with a local header + { + ZipFileHeader *recFile = (ZipFileHeader *)workBuf; + DFextZipDirEntry *zipDirEntry = zipHandle->zipFileEntries + (i * sizeof(zipDirEntry)); + + // find local file info, read it and verify signature + if (fseek(zipFile, recDir->relativeOffsetOflocalHeader, SEEK_SET) + || fread(workBuf, 1, sizeof(ZipFileHeader), zipFile) < sizeof(ZipFileHeader) + || recFile->signature != ZipFileHeader_signature) + return -1; + + // Save information + zipDirEntry->compressedSize = recFile->compressedSize; + zipDirEntry->fileNameLength = recFile->fileNameLength; + zipDirEntry->uncompressedSize = recFile->uncompressedSize; + zipDirEntry->compressionMethod = recDir->compressionMethod; + + // Add filename + zipDirEntry->fileName = xmalloc(zipDirEntry->fileNameLength + 1); + if (fread(zipDirEntry->fileName, 1, zipDirEntry->fileNameLength, zipFile) < (unsigned long)zipDirEntry->fileNameLength) + return -1; + zipDirEntry->fileName[zipDirEntry->fileNameLength] = '\0'; + + // skip extra field + if (fseek(zipFile, recFile->extraFieldLength, SEEK_CUR)) + return -1; + zipDirEntry->offset = ftell(zipFile); + } }; return 0; @@ -182,6 +207,82 @@ DFextZipHandleP DFextZipOpen(const char *zipFilename) { +unsigned char *DFextZipReadFile(DFextZipHandleP zipHandle, DFextZipDirEntryP zipEntry) { + unsigned char *fileBuf = xmalloc(zipEntry->uncompressedSize); + +#if 0 + // Some files are uncompressed + if (zipFile->compressionMethod == 0) { + if (fread(buffer, 1, header->uncompressedSize, zip) < + header->uncompressedSize || ferror(zip)) + return Z_ERRNO; + } + unsigned char *bytes = (unsigned char *)buffer; // cast + long compressedLeft, uncompressedLeft; + z_stream strm; + int ret; + + else if (header->compressionMethod == 8) { // Deflate - using zlib + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + + strm.avail_in = 0; + strm.next_in = Z_NULL; + + // Use inflateInit2 with negative window bits to indicate raw data + if ((ret = inflateInit2(&strm, -MAX_WBITS)) != Z_OK) + return ret; // Zlib errors are negative + + // Inflate compressed data + for (compressedLeft = header->compressedSize, + uncompressedLeft = header->uncompressedSize; + compressedLeft && uncompressedLeft && ret != Z_STREAM_END; + compressedLeft -= strm.avail_in) { + // Read next chunk + strm.avail_in = fread(jzBuffer, 1, + (sizeof(jzBuffer) < compressedLeft) ? + sizeof(jzBuffer) : compressedLeft, zip); + + if (strm.avail_in == 0 || ferror(zip)) { + inflateEnd(&strm); + return Z_ERRNO; + } + + strm.next_in = jzBuffer; + strm.avail_out = uncompressedLeft; + strm.next_out = bytes; + + compressedLeft -= strm.avail_in; // inflate will change avail_in + + ret = inflate(&strm, Z_NO_FLUSH); + + if (ret == Z_STREAM_ERROR) return ret; // shouldn't happen + + switch (ret) { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: case Z_MEM_ERROR: + (void)inflateEnd(&strm); + return ret; + } + + bytes += uncompressedLeft - strm.avail_out; // bytes uncompressed + uncompressedLeft = strm.avail_out; + } + + inflateEnd(&strm); + } + else { + return Z_ERRNO; + } +#endif + return Z_OK; + return NULL; +} + + +