├── English.lproj └── InfoPlist.strings ├── .gitignore ├── NSString+Additions.m ├── NSString+Additions.h ├── GNJUnZip.h ├── README.rst ├── Info.plist ├── GNJUnZip.m ├── GenerateThumbnailForURL.m ├── minizip ├── ioapi.h ├── ioapi.c ├── unzip.h └── unzip.c ├── main.c ├── GeneratePreviewForURL.m └── EPUBQLGenerator.xcodeproj └── project.pbxproj /English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | build/ 3 | *.pbxuser 4 | *.mode1v3 5 | *.mode2v3 6 | *.perspectivev3 7 | *.xcworkspace 8 | xcuserdata 9 | -------------------------------------------------------------------------------- /NSString+Additions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Additions.m 3 | // EPUBQLGenerator 4 | // 5 | // Created by Genji on 2013/03/10. 6 | // Copyright 2013 Genji App. All rights reserved. 7 | // 8 | 9 | #import "NSString+Additions.h" 10 | 11 | @implementation NSString (Additions) 12 | 13 | - (NSString *)stringByForciblyResolvingSymlinksInPath 14 | { 15 | if([self isAbsolutePath]) return [self stringByResolvingSymlinksInPath]; 16 | 17 | NSString *absolutePath = [@"/" stringByAppendingPathComponent:self]; 18 | NSString *standardizedPath = [absolutePath stringByResolvingSymlinksInPath]; 19 | return [standardizedPath substringFromIndex:1]; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /NSString+Additions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Additions.h 3 | // EPUBQLGenerator 4 | // 5 | // Created by Genji on 2013/03/10. 6 | // Copyright 2013 Genji App. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (Additions) 12 | 13 | /** 14 | * Returns a new string made from the receiver by forcibly resolving all symbolic links 15 | * and standardizing path. stringByResolvingSymlinksInPath doesn't resolve references 16 | * to parent directory, but this method forcibly resolves them by prepend "/" to the path, 17 | * then removes "/" from string and returns it. 18 | **/ 19 | - (NSString *)stringByForciblyResolvingSymlinksInPath; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /GNJUnZip.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNJUnZip.h 3 | // EPUBImporter 4 | // 5 | // Created by Genji on 11/07/12. 6 | // Copyright 2011 Genji App. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "minizip/unzip.h" 11 | 12 | /** 13 | * GNJUnZip object is a wrapper object for minizip's unzip. 14 | */ 15 | @interface GNJUnZip : NSObject 16 | { 17 | unzFile unzipFile_; 18 | NSString *path_; 19 | } 20 | 21 | /** The path of zip file */ 22 | @property (nonatomic, readonly) NSString *path; 23 | 24 | /** The items contained in the zip archive. */ 25 | @property (nonatomic, readonly) NSArray *items; 26 | 27 | - (id)initWithZipFile:(NSString *)path; 28 | - (NSData *)dataWithContentsOfFile:(NSString *)path; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | EPUBQLGenerator 3 | ================= 4 | 5 | EPUBQLGenerator is Quick Look Generator for EPUB. 6 | 7 | 8 | Install 9 | ======= 10 | 11 | Copy EPUBQLGenerator.qlgenerator to ``/Library/QuickLook`` or ``~/Library/QuickLook``. 12 | 13 | 14 | Restrictions 15 | ============ 16 | 17 | #. Can't apply CSS which is linked from HTML 18 | #. Previews up to 10 HTML files per a EPUB 19 | #. Shows up to 10 images per a HTML file 20 | 21 | 22 | User Preferences 23 | ================ 24 | 25 | You can change the default behavior above. 26 | 27 | On Terminal.app, by typing command as follows, you can change the maximum number of loading HTML file:: 28 | 29 | defaults write jp.genji.qlgenerator.EPUBQLGenerator MaximumNumberOfLoadingHTML -integer 5 30 | 31 | If ``-1`` is specified, all of HTML are previewed. 32 | 33 | By typing command as follows, you can change the maximum number of loading image:: 34 | 35 | defaults write jp.genji.qlgenerator.EPUBQLGenerator MaximumNumberOfLoadingImage -integer 5 36 | 37 | If ``-1`` is specified, all of images are shown. 38 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDocumentTypes 8 | 9 | 10 | CFBundleTypeRole 11 | QLGenerator 12 | LSItemContentTypes 13 | 14 | org.idpf.epub-container 15 | 16 | 17 | 18 | CFBundleExecutable 19 | ${EXECUTABLE_NAME} 20 | CFBundleIconFile 21 | 22 | CFBundleIdentifier 23 | jp.genji.qlgenerator.${PRODUCT_NAME:identifier} 24 | CFBundleInfoDictionaryVersion 25 | 6.0 26 | CFBundleName 27 | ${PRODUCT_NAME} 28 | CFBundleShortVersionString 29 | 1.1.3 30 | CFBundleVersion 31 | 7 32 | CFPlugInDynamicRegisterFunction 33 | 34 | CFPlugInDynamicRegistration 35 | NO 36 | CFPlugInFactories 37 | 38 | 6D1DA232-34DC-400C-A00A-7E4B076DF00B 39 | QuickLookGeneratorPluginFactory 40 | 41 | CFPlugInTypes 42 | 43 | 5E2D9680-5022-40FA-B806-43349622E5B9 44 | 45 | 6D1DA232-34DC-400C-A00A-7E4B076DF00B 46 | 47 | 48 | CFPlugInUnloadFunction 49 | 50 | NSHumanReadableCopyright 51 | Copyright (c) 2011-2012 Genji App. 52 | QLNeedsToBeRunInMainThread 53 | 54 | QLPreviewHeight 55 | 600 56 | QLPreviewWidth 57 | 800 58 | QLSupportsConcurrentRequests 59 | 60 | QLThumbnailMinimumSize 61 | 17 62 | UTImportedTypeDeclarations 63 | 64 | 65 | UTTypeConformsTo 66 | 67 | public.data 68 | public.item 69 | public.composite-content 70 | public.content 71 | 72 | UTTypeIdentifier 73 | org.idpf.epub-container 74 | UTTypeTagSpecification 75 | 76 | com.apple.ostype 77 | EPUB 78 | public.filename-extension 79 | 80 | epub 81 | 82 | public.mime-type 83 | application/epub+zip 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /GNJUnZip.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNJUnZip.m 3 | // EPUBImporter 4 | // 5 | // Created by Genji on 11/07/12. 6 | // Copyright 2011 Genji App. All rights reserved. 7 | // 8 | 9 | #import "GNJUnZip.h" 10 | 11 | @implementation GNJUnZip 12 | 13 | @synthesize path = path_; 14 | 15 | /** 16 | * Initializes and returns an unzip object. 17 | * This object opens an unzFile object that 18 | * represents the zip file specified by a given path. 19 | * 20 | * @param path The absolute path of the zip file from which to opens. 21 | */ 22 | - (id)initWithZipFile:(NSString *)path 23 | { 24 | if((self = [self init]) != nil) { 25 | unzipFile_ = unzOpen([path fileSystemRepresentation]); 26 | if(unzipFile_ == NULL) { 27 | NSLog(@"error: cannot open zip archive specified by path '%@'", path); 28 | return nil; 29 | } 30 | path_ = [path copy]; 31 | } 32 | 33 | return self; 34 | } 35 | 36 | /** 37 | * Deallocates the memory occupied by the receiver, 38 | * and closes unzFile object. 39 | */ 40 | - (void)dealloc 41 | { 42 | if(unzipFile_) unzClose(unzipFile_); 43 | [path_ release]; 44 | 45 | [super dealloc]; 46 | } 47 | 48 | /** 49 | * Returns an array containing the files' paths in zip archive. 50 | * 51 | * @return an array containing the files' paths in zip archive. 52 | */ 53 | - (NSArray *)items 54 | { 55 | if(!unzipFile_) { 56 | NSLog(@"error: unzFile is not opened yet"); 57 | return nil; 58 | } 59 | 60 | if(unzGoToFirstFile(unzipFile_) != UNZ_OK) { 61 | NSLog(@"error: cannot go to first file in zipfile"); 62 | return nil; 63 | } 64 | 65 | NSMutableArray *itemsArray = [NSMutableArray array]; 66 | do { 67 | char rawFilename[512]; 68 | unz_file_info fileInfo; 69 | unzGetCurrentFileInfo(unzipFile_, &fileInfo, 70 | rawFilename, sizeof(rawFilename), 71 | NULL, 0, NULL, 0); 72 | NSString *filename = [NSString stringWithCString:rawFilename 73 | encoding:NSUTF8StringEncoding]; 74 | [itemsArray addObject:filename]; 75 | } while(unzGoToNextFile(unzipFile_) != UNZ_END_OF_LIST_OF_FILE); 76 | 77 | return itemsArray; 78 | } 79 | 80 | /** 81 | * Creates and returns a data object by reading every byte 82 | * from the file specified by a given path in zip archive. 83 | * 84 | * @param path The path of the file from which to read data. 85 | * @return A data object by reading every byte from the file specified by path. 86 | * Returns nil if the data object could not be created. 87 | */ 88 | - (NSData *)dataWithContentsOfFile:(NSString *)path 89 | { 90 | if(!unzipFile_) { 91 | NSLog(@"error: unzFile is not opened yet"); 92 | return nil; 93 | } 94 | 95 | const char *rawFilename = [path fileSystemRepresentation]; 96 | if(unzLocateFile(unzipFile_, rawFilename, 0) != UNZ_OK) { 97 | NSLog(@"error: cannot locate file '%@'", path); 98 | return nil; 99 | } 100 | 101 | if(unzOpenCurrentFile(unzipFile_) != UNZ_OK) { 102 | NSLog(@"error: cannot open '%@'", path); 103 | return nil; 104 | } 105 | 106 | NSMutableData *data = [NSMutableData data]; 107 | unsigned int bufferSize = 1024; 108 | void *buffer = (void *)malloc(bufferSize); 109 | while(1) { 110 | int results = unzReadCurrentFile(unzipFile_, buffer, bufferSize); 111 | if(results < 0) { 112 | NSLog(@"error: occurred reading data error (error code: %d)", results); 113 | unzCloseCurrentFile(unzipFile_); 114 | return nil; 115 | } 116 | else if(results == 0) break; 117 | [data appendBytes:buffer length:results]; 118 | } 119 | unzCloseCurrentFile(unzipFile_); 120 | free(buffer); 121 | 122 | return data; 123 | } 124 | 125 | @end 126 | -------------------------------------------------------------------------------- /GenerateThumbnailForURL.m: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #import 5 | #import "GNJUnZip.h" 6 | #import "NSString+Additions.h" 7 | 8 | /* ----------------------------------------------------------------------------- 9 | Generate a thumbnail for file 10 | 11 | This function's job is to create thumbnail for designated file as fast as possible 12 | ----------------------------------------------------------------------------- */ 13 | 14 | OSStatus GenerateThumbnailForURL(void *thisInterface, 15 | QLThumbnailRequestRef thumbnail, 16 | CFURLRef url, 17 | CFStringRef contentTypeUTI, 18 | CFDictionaryRef options, 19 | CGSize maxSize) 20 | { 21 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 22 | 23 | NSString *path = [(NSURL *)url path]; 24 | GNJUnZip *unzip = [[GNJUnZip alloc] initWithZipFile:path]; 25 | 26 | NSCharacterSet *setForTrim = [NSCharacterSet whitespaceAndNewlineCharacterSet]; 27 | 28 | NSData *xmlData = [unzip dataWithContentsOfFile:@"META-INF/container.xml"]; 29 | if(!xmlData) { 30 | [unzip release]; 31 | [pool release]; 32 | return noErr; 33 | } 34 | 35 | NSXMLDocument *xmlDoc = [[NSXMLDocument alloc] initWithData:xmlData 36 | options:NSXMLDocumentTidyXML 37 | error:NULL]; 38 | if(!xmlDoc) { 39 | [unzip release]; 40 | [pool release]; 41 | return noErr; 42 | } 43 | 44 | NSString *xpath = @"/container/rootfiles/rootfile/@full-path"; 45 | NSArray *nodes = [xmlDoc nodesForXPath:xpath error:NULL]; 46 | if(![nodes count]) { 47 | [xmlDoc release]; 48 | [unzip release]; 49 | [pool release]; 50 | return noErr; 51 | } 52 | 53 | NSString *fullPathValue = [[nodes objectAtIndex:0] stringValue]; 54 | NSString *opfFilePath = [fullPathValue stringByTrimmingCharactersInSet:setForTrim]; 55 | opfFilePath = [opfFilePath stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 56 | [xmlDoc release]; 57 | 58 | xmlData = [unzip dataWithContentsOfFile:opfFilePath]; 59 | if(!xmlData) { 60 | [unzip release]; 61 | [pool release]; 62 | return noErr; 63 | } 64 | 65 | xmlDoc = [[NSXMLDocument alloc] initWithData:xmlData 66 | options:NSXMLDocumentTidyXML 67 | error:NULL]; 68 | if(!xmlDoc) { 69 | [unzip release]; 70 | [pool release]; 71 | return noErr; 72 | } 73 | 74 | NSString *coverImagePath = nil; 75 | xpath = @"/package/manifest/item[contains(concat(' ', normalize-space(@properties), ' '), ' cover-image ')]/@href"; 76 | nodes = [xmlDoc nodesForXPath:xpath error:NULL]; 77 | if([nodes count]) coverImagePath = [[nodes objectAtIndex:0] stringValue]; 78 | else { 79 | xpath = @"/package/metadata/meta[@name='cover']/@content"; 80 | nodes = [xmlDoc nodesForXPath:xpath error:NULL]; 81 | if([nodes count]) { 82 | NSString *coverImageId = [[[nodes objectAtIndex:0] stringValue] stringByTrimmingCharactersInSet:setForTrim]; 83 | xpath = [NSString stringWithFormat:@"/package/manifest/item[@id='%@']/@href", 84 | coverImageId]; 85 | NSArray *coverImageItemHrefs = [xmlDoc nodesForXPath:xpath error:NULL]; 86 | if([coverImageItemHrefs count]) { 87 | coverImagePath = [[coverImageItemHrefs objectAtIndex:0] stringValue]; 88 | } 89 | } 90 | } 91 | 92 | if([coverImagePath length]) { 93 | coverImagePath = [coverImagePath stringByTrimmingCharactersInSet:setForTrim]; 94 | coverImagePath = [coverImagePath stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 95 | if([coverImagePath isAbsolutePath]) coverImagePath = [coverImagePath substringFromIndex:1]; 96 | else { 97 | NSString *opfBasePath = [opfFilePath stringByDeletingLastPathComponent]; 98 | coverImagePath = [opfBasePath stringByAppendingPathComponent:coverImagePath]; 99 | } 100 | coverImagePath = [coverImagePath stringByForciblyResolvingSymlinksInPath]; 101 | NSData *coverImageData = [unzip dataWithContentsOfFile:coverImagePath]; 102 | NSImage *coverImage = [[[NSImage alloc] initWithData:coverImageData] autorelease]; 103 | if([coverImage isValid]) { 104 | CGSize maximumSize = QLThumbnailRequestGetMaximumSize(thumbnail); 105 | NSSize imageSize = [coverImage size]; 106 | CGFloat scale = maximumSize.width / ((imageSize.width > imageSize.height) ? imageSize.width : imageSize.height); 107 | NSSize newSize = NSMakeSize(imageSize.width * scale, imageSize.height * scale); 108 | NSImage *resizedImage = [[[NSImage alloc] initWithSize:newSize] autorelease]; 109 | [resizedImage lockFocus]; 110 | [coverImage drawInRect:NSMakeRect(0.0, 0.0, newSize.width, newSize.height) 111 | fromRect:NSMakeRect(0.0, 0.0, imageSize.width, imageSize.height) 112 | operation:NSCompositeSourceOver 113 | fraction:1.0]; 114 | [resizedImage unlockFocus]; 115 | NSData *resizedImageData = [resizedImage TIFFRepresentation]; 116 | QLThumbnailRequestSetImageWithData(thumbnail, (CFDataRef)resizedImageData, NULL); 117 | } 118 | } 119 | 120 | [xmlDoc release]; 121 | [unzip release]; 122 | [pool release]; 123 | 124 | return noErr; 125 | } 126 | 127 | void CancelThumbnailGeneration(void* thisInterface, 128 | QLThumbnailRequestRef thumbnail) 129 | { 130 | // implement only if supported 131 | } 132 | -------------------------------------------------------------------------------- /minizip/ioapi.h: -------------------------------------------------------------------------------- 1 | /* ioapi.h -- IO base function header for compress/uncompress .zip 2 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) 3 | 4 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) 5 | 6 | Modifications for Zip64 support 7 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) 8 | 9 | For more info read MiniZip_info.txt 10 | 11 | Changes 12 | 13 | Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) 14 | Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. 15 | More if/def section may be needed to support other platforms 16 | Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. 17 | (but you should use iowin32.c for windows instead) 18 | 19 | */ 20 | 21 | #ifndef _ZLIBIOAPI64_H 22 | #define _ZLIBIOAPI64_H 23 | 24 | #if (!defined(_WIN32)) && (!defined(WIN32)) 25 | 26 | // Linux needs this to support file operation on files larger then 4+GB 27 | // But might need better if/def to select just the platforms that needs them. 28 | 29 | #ifndef __USE_FILE_OFFSET64 30 | #define __USE_FILE_OFFSET64 31 | #endif 32 | #ifndef __USE_LARGEFILE64 33 | #define __USE_LARGEFILE64 34 | #endif 35 | #ifndef _LARGEFILE64_SOURCE 36 | #define _LARGEFILE64_SOURCE 37 | #endif 38 | #ifndef _FILE_OFFSET_BIT 39 | #define _FILE_OFFSET_BIT 64 40 | #endif 41 | #endif 42 | 43 | #include 44 | #include 45 | #include "zlib.h" 46 | 47 | #if defined(USE_FILE32API) 48 | #define fopen64 fopen 49 | #define ftello64 ftell 50 | #define fseeko64 fseek 51 | #else 52 | #ifdef _MSC_VER 53 | #define fopen64 fopen 54 | #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) 55 | #define ftello64 _ftelli64 56 | #define fseeko64 _fseeki64 57 | #else // old MSC 58 | #define ftello64 ftell 59 | #define fseeko64 fseek 60 | #endif 61 | #endif 62 | #endif 63 | 64 | /* 65 | #ifndef ZPOS64_T 66 | #ifdef _WIN32 67 | #define ZPOS64_T fpos_t 68 | #else 69 | #include 70 | #define ZPOS64_T uint64_t 71 | #endif 72 | #endif 73 | */ 74 | 75 | #ifdef HAVE_MINIZIP64_CONF_H 76 | #include "mz64conf.h" 77 | #endif 78 | 79 | /* a type choosen by DEFINE */ 80 | #ifdef HAVE_64BIT_INT_CUSTOM 81 | typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; 82 | #else 83 | #ifdef HAS_STDINT_H 84 | #include "stdint.h" 85 | typedef uint64_t ZPOS64_T; 86 | #else 87 | 88 | 89 | #if defined(_MSC_VER) || defined(__BORLANDC__) 90 | typedef unsigned __int64 ZPOS64_T; 91 | #else 92 | typedef unsigned long long int ZPOS64_T; 93 | #endif 94 | #endif 95 | #endif 96 | 97 | 98 | 99 | #ifdef __cplusplus 100 | extern "C" { 101 | #endif 102 | 103 | 104 | #define ZLIB_FILEFUNC_SEEK_CUR (1) 105 | #define ZLIB_FILEFUNC_SEEK_END (2) 106 | #define ZLIB_FILEFUNC_SEEK_SET (0) 107 | 108 | #define ZLIB_FILEFUNC_MODE_READ (1) 109 | #define ZLIB_FILEFUNC_MODE_WRITE (2) 110 | #define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) 111 | 112 | #define ZLIB_FILEFUNC_MODE_EXISTING (4) 113 | #define ZLIB_FILEFUNC_MODE_CREATE (8) 114 | 115 | 116 | #ifndef ZCALLBACK 117 | #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) 118 | #define ZCALLBACK CALLBACK 119 | #else 120 | #define ZCALLBACK 121 | #endif 122 | #endif 123 | 124 | 125 | 126 | 127 | typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); 128 | typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); 129 | typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); 130 | typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); 131 | typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); 132 | 133 | typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); 134 | typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); 135 | 136 | 137 | /* here is the "old" 32 bits structure structure */ 138 | typedef struct zlib_filefunc_def_s 139 | { 140 | open_file_func zopen_file; 141 | read_file_func zread_file; 142 | write_file_func zwrite_file; 143 | tell_file_func ztell_file; 144 | seek_file_func zseek_file; 145 | close_file_func zclose_file; 146 | testerror_file_func zerror_file; 147 | voidpf opaque; 148 | } zlib_filefunc_def; 149 | 150 | typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); 151 | typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); 152 | typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); 153 | 154 | typedef struct zlib_filefunc64_def_s 155 | { 156 | open64_file_func zopen64_file; 157 | read_file_func zread_file; 158 | write_file_func zwrite_file; 159 | tell64_file_func ztell64_file; 160 | seek64_file_func zseek64_file; 161 | close_file_func zclose_file; 162 | testerror_file_func zerror_file; 163 | voidpf opaque; 164 | } zlib_filefunc64_def; 165 | 166 | void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); 167 | void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); 168 | 169 | /* now internal definition, only for zip.c and unzip.h */ 170 | typedef struct zlib_filefunc64_32_def_s 171 | { 172 | zlib_filefunc64_def zfile_func64; 173 | open_file_func zopen32_file; 174 | tell_file_func ztell32_file; 175 | seek_file_func zseek32_file; 176 | } zlib_filefunc64_32_def; 177 | 178 | 179 | #define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) 180 | #define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) 181 | //#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) 182 | //#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) 183 | #define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) 184 | #define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) 185 | 186 | voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); 187 | long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); 188 | ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); 189 | 190 | void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); 191 | 192 | #define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) 193 | #define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) 194 | #define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) 195 | 196 | #ifdef __cplusplus 197 | } 198 | #endif 199 | 200 | #endif 201 | -------------------------------------------------------------------------------- /minizip/ioapi.c: -------------------------------------------------------------------------------- 1 | /* ioapi.h -- IO base function header for compress/uncompress .zip 2 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) 3 | 4 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) 5 | 6 | Modifications for Zip64 support 7 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) 8 | 9 | For more info read MiniZip_info.txt 10 | 11 | */ 12 | 13 | #if (defined(_WIN32)) 14 | #define _CRT_SECURE_NO_WARNINGS 15 | #endif 16 | 17 | #include "ioapi.h" 18 | 19 | voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) 20 | { 21 | if (pfilefunc->zfile_func64.zopen64_file != NULL) 22 | return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); 23 | else 24 | { 25 | return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); 26 | } 27 | } 28 | 29 | long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) 30 | { 31 | if (pfilefunc->zfile_func64.zseek64_file != NULL) 32 | return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); 33 | else 34 | { 35 | uLong offsetTruncated = (uLong)offset; 36 | if (offsetTruncated != offset) 37 | return -1; 38 | else 39 | return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); 40 | } 41 | } 42 | 43 | ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) 44 | { 45 | if (pfilefunc->zfile_func64.zseek64_file != NULL) 46 | return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); 47 | else 48 | { 49 | uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); 50 | if ((tell_uLong) == ((uLong)-1)) 51 | return (ZPOS64_T)-1; 52 | else 53 | return tell_uLong; 54 | } 55 | } 56 | 57 | void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) 58 | { 59 | p_filefunc64_32->zfile_func64.zopen64_file = NULL; 60 | p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; 61 | p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; 62 | p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; 63 | p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; 64 | p_filefunc64_32->zfile_func64.ztell64_file = NULL; 65 | p_filefunc64_32->zfile_func64.zseek64_file = NULL; 66 | p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; 67 | p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; 68 | p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; 69 | p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; 70 | p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; 71 | } 72 | 73 | 74 | 75 | static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); 76 | static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); 77 | static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); 78 | static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); 79 | static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); 80 | static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); 81 | static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); 82 | 83 | static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) 84 | { 85 | FILE* file = NULL; 86 | const char* mode_fopen = NULL; 87 | if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) 88 | mode_fopen = "rb"; 89 | else 90 | if (mode & ZLIB_FILEFUNC_MODE_EXISTING) 91 | mode_fopen = "r+b"; 92 | else 93 | if (mode & ZLIB_FILEFUNC_MODE_CREATE) 94 | mode_fopen = "wb"; 95 | 96 | if ((filename!=NULL) && (mode_fopen != NULL)) 97 | file = fopen(filename, mode_fopen); 98 | return file; 99 | } 100 | 101 | static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) 102 | { 103 | FILE* file = NULL; 104 | const char* mode_fopen = NULL; 105 | if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) 106 | mode_fopen = "rb"; 107 | else 108 | if (mode & ZLIB_FILEFUNC_MODE_EXISTING) 109 | mode_fopen = "r+b"; 110 | else 111 | if (mode & ZLIB_FILEFUNC_MODE_CREATE) 112 | mode_fopen = "wb"; 113 | 114 | if ((filename!=NULL) && (mode_fopen != NULL)) 115 | file = fopen64((const char*)filename, mode_fopen); 116 | return file; 117 | } 118 | 119 | 120 | static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) 121 | { 122 | uLong ret; 123 | ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); 124 | return ret; 125 | } 126 | 127 | static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) 128 | { 129 | uLong ret; 130 | ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); 131 | return ret; 132 | } 133 | 134 | static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) 135 | { 136 | long ret; 137 | ret = ftell((FILE *)stream); 138 | return ret; 139 | } 140 | 141 | 142 | static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) 143 | { 144 | ZPOS64_T ret; 145 | ret = ftello64((FILE *)stream); 146 | return ret; 147 | } 148 | 149 | static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) 150 | { 151 | int fseek_origin=0; 152 | long ret; 153 | switch (origin) 154 | { 155 | case ZLIB_FILEFUNC_SEEK_CUR : 156 | fseek_origin = SEEK_CUR; 157 | break; 158 | case ZLIB_FILEFUNC_SEEK_END : 159 | fseek_origin = SEEK_END; 160 | break; 161 | case ZLIB_FILEFUNC_SEEK_SET : 162 | fseek_origin = SEEK_SET; 163 | break; 164 | default: return -1; 165 | } 166 | ret = 0; 167 | if (fseek((FILE *)stream, offset, fseek_origin) != 0) 168 | ret = -1; 169 | return ret; 170 | } 171 | 172 | static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) 173 | { 174 | int fseek_origin=0; 175 | long ret; 176 | switch (origin) 177 | { 178 | case ZLIB_FILEFUNC_SEEK_CUR : 179 | fseek_origin = SEEK_CUR; 180 | break; 181 | case ZLIB_FILEFUNC_SEEK_END : 182 | fseek_origin = SEEK_END; 183 | break; 184 | case ZLIB_FILEFUNC_SEEK_SET : 185 | fseek_origin = SEEK_SET; 186 | break; 187 | default: return -1; 188 | } 189 | ret = 0; 190 | 191 | if(fseeko64((FILE *)stream, offset, fseek_origin) != 0) 192 | ret = -1; 193 | 194 | return ret; 195 | } 196 | 197 | 198 | static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) 199 | { 200 | int ret; 201 | ret = fclose((FILE *)stream); 202 | return ret; 203 | } 204 | 205 | static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) 206 | { 207 | int ret; 208 | ret = ferror((FILE *)stream); 209 | return ret; 210 | } 211 | 212 | void fill_fopen_filefunc (pzlib_filefunc_def) 213 | zlib_filefunc_def* pzlib_filefunc_def; 214 | { 215 | pzlib_filefunc_def->zopen_file = fopen_file_func; 216 | pzlib_filefunc_def->zread_file = fread_file_func; 217 | pzlib_filefunc_def->zwrite_file = fwrite_file_func; 218 | pzlib_filefunc_def->ztell_file = ftell_file_func; 219 | pzlib_filefunc_def->zseek_file = fseek_file_func; 220 | pzlib_filefunc_def->zclose_file = fclose_file_func; 221 | pzlib_filefunc_def->zerror_file = ferror_file_func; 222 | pzlib_filefunc_def->opaque = NULL; 223 | } 224 | 225 | void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) 226 | { 227 | pzlib_filefunc_def->zopen64_file = fopen64_file_func; 228 | pzlib_filefunc_def->zread_file = fread_file_func; 229 | pzlib_filefunc_def->zwrite_file = fwrite_file_func; 230 | pzlib_filefunc_def->ztell64_file = ftell64_file_func; 231 | pzlib_filefunc_def->zseek64_file = fseek64_file_func; 232 | pzlib_filefunc_def->zclose_file = fclose_file_func; 233 | pzlib_filefunc_def->zerror_file = ferror_file_func; 234 | pzlib_filefunc_def->opaque = NULL; 235 | } 236 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | //============================================================================== 2 | // 3 | // DO NO MODIFY THE CONTENT OF THIS FILE 4 | // 5 | // This file contains the generic CFPlug-in code necessary for your generator 6 | // To complete your generator implement the function in GenerateThumbnailForURL/GeneratePreviewForURL.c 7 | // 8 | //============================================================================== 9 | 10 | 11 | 12 | 13 | 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | // ----------------------------------------------------------------------------- 21 | // constants 22 | // ----------------------------------------------------------------------------- 23 | 24 | // Don't modify this line 25 | #define PLUGIN_ID "6D1DA232-34DC-400C-A00A-7E4B076DF00B" 26 | 27 | // 28 | // Below is the generic glue code for all plug-ins. 29 | // 30 | // You should not have to modify this code aside from changing 31 | // names if you decide to change the names defined in the Info.plist 32 | // 33 | 34 | 35 | // ----------------------------------------------------------------------------- 36 | // typedefs 37 | // ----------------------------------------------------------------------------- 38 | 39 | // The thumbnail generation function to be implemented in GenerateThumbnailForURL.c 40 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize); 41 | void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail); 42 | 43 | // The preview generation function to be implemented in GeneratePreviewForURL.c 44 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options); 45 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview); 46 | 47 | // The layout for an instance of QuickLookGeneratorPlugIn 48 | typedef struct __QuickLookGeneratorPluginType 49 | { 50 | void *conduitInterface; 51 | CFUUIDRef factoryID; 52 | UInt32 refCount; 53 | } QuickLookGeneratorPluginType; 54 | 55 | // ----------------------------------------------------------------------------- 56 | // prototypes 57 | // ----------------------------------------------------------------------------- 58 | // Forward declaration for the IUnknown implementation. 59 | // 60 | 61 | QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID); 62 | void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance); 63 | HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv); 64 | void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID); 65 | ULONG QuickLookGeneratorPluginAddRef(void *thisInstance); 66 | ULONG QuickLookGeneratorPluginRelease(void *thisInstance); 67 | 68 | // ----------------------------------------------------------------------------- 69 | // myInterfaceFtbl definition 70 | // ----------------------------------------------------------------------------- 71 | // The QLGeneratorInterfaceStruct function table. 72 | // 73 | static QLGeneratorInterfaceStruct myInterfaceFtbl = { 74 | NULL, 75 | QuickLookGeneratorQueryInterface, 76 | QuickLookGeneratorPluginAddRef, 77 | QuickLookGeneratorPluginRelease, 78 | NULL, 79 | NULL, 80 | NULL, 81 | NULL 82 | }; 83 | 84 | 85 | // ----------------------------------------------------------------------------- 86 | // AllocQuickLookGeneratorPluginType 87 | // ----------------------------------------------------------------------------- 88 | // Utility function that allocates a new instance. 89 | // You can do some initial setup for the generator here if you wish 90 | // like allocating globals etc... 91 | // 92 | QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID) 93 | { 94 | QuickLookGeneratorPluginType *theNewInstance; 95 | 96 | theNewInstance = (QuickLookGeneratorPluginType *)malloc(sizeof(QuickLookGeneratorPluginType)); 97 | memset(theNewInstance,0,sizeof(QuickLookGeneratorPluginType)); 98 | 99 | /* Point to the function table Malloc enough to store the stuff and copy the filler from myInterfaceFtbl over */ 100 | theNewInstance->conduitInterface = malloc(sizeof(QLGeneratorInterfaceStruct)); 101 | memcpy(theNewInstance->conduitInterface,&myInterfaceFtbl,sizeof(QLGeneratorInterfaceStruct)); 102 | 103 | /* Retain and keep an open instance refcount for each factory. */ 104 | theNewInstance->factoryID = CFRetain(inFactoryID); 105 | CFPlugInAddInstanceForFactory(inFactoryID); 106 | 107 | /* This function returns the IUnknown interface so set the refCount to one. */ 108 | theNewInstance->refCount = 1; 109 | return theNewInstance; 110 | } 111 | 112 | // ----------------------------------------------------------------------------- 113 | // DeallocQuickLookGeneratorPluginType 114 | // ----------------------------------------------------------------------------- 115 | // Utility function that deallocates the instance when 116 | // the refCount goes to zero. 117 | // In the current implementation generator interfaces are never deallocated 118 | // but implement this as this might change in the future 119 | // 120 | void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance) 121 | { 122 | CFUUIDRef theFactoryID; 123 | 124 | theFactoryID = thisInstance->factoryID; 125 | /* Free the conduitInterface table up */ 126 | free(thisInstance->conduitInterface); 127 | 128 | /* Free the instance structure */ 129 | free(thisInstance); 130 | if (theFactoryID){ 131 | CFPlugInRemoveInstanceForFactory(theFactoryID); 132 | CFRelease(theFactoryID); 133 | } 134 | } 135 | 136 | // ----------------------------------------------------------------------------- 137 | // QuickLookGeneratorQueryInterface 138 | // ----------------------------------------------------------------------------- 139 | // Implementation of the IUnknown QueryInterface function. 140 | // 141 | HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv) 142 | { 143 | CFUUIDRef interfaceID; 144 | 145 | interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid); 146 | 147 | if (CFEqual(interfaceID,kQLGeneratorCallbacksInterfaceID)){ 148 | /* If the Right interface was requested, bump the ref count, 149 | * set the ppv parameter equal to the instance, and 150 | * return good status. 151 | */ 152 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GenerateThumbnailForURL = GenerateThumbnailForURL; 153 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelThumbnailGeneration = CancelThumbnailGeneration; 154 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GeneratePreviewForURL = GeneratePreviewForURL; 155 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelPreviewGeneration = CancelPreviewGeneration; 156 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->AddRef(thisInstance); 157 | *ppv = thisInstance; 158 | CFRelease(interfaceID); 159 | return S_OK; 160 | }else{ 161 | /* Requested interface unknown, bail with error. */ 162 | *ppv = NULL; 163 | CFRelease(interfaceID); 164 | return E_NOINTERFACE; 165 | } 166 | } 167 | 168 | // ----------------------------------------------------------------------------- 169 | // QuickLookGeneratorPluginAddRef 170 | // ----------------------------------------------------------------------------- 171 | // Implementation of reference counting for this type. Whenever an interface 172 | // is requested, bump the refCount for the instance. NOTE: returning the 173 | // refcount is a convention but is not required so don't rely on it. 174 | // 175 | ULONG QuickLookGeneratorPluginAddRef(void *thisInstance) 176 | { 177 | ((QuickLookGeneratorPluginType *)thisInstance )->refCount += 1; 178 | return ((QuickLookGeneratorPluginType*) thisInstance)->refCount; 179 | } 180 | 181 | // ----------------------------------------------------------------------------- 182 | // QuickLookGeneratorPluginRelease 183 | // ----------------------------------------------------------------------------- 184 | // When an interface is released, decrement the refCount. 185 | // If the refCount goes to zero, deallocate the instance. 186 | // 187 | ULONG QuickLookGeneratorPluginRelease(void *thisInstance) 188 | { 189 | ((QuickLookGeneratorPluginType*)thisInstance)->refCount -= 1; 190 | if (((QuickLookGeneratorPluginType*)thisInstance)->refCount == 0){ 191 | DeallocQuickLookGeneratorPluginType((QuickLookGeneratorPluginType*)thisInstance ); 192 | return 0; 193 | }else{ 194 | return ((QuickLookGeneratorPluginType*) thisInstance )->refCount; 195 | } 196 | } 197 | 198 | // ----------------------------------------------------------------------------- 199 | // QuickLookGeneratorPluginFactory 200 | // ----------------------------------------------------------------------------- 201 | void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID) 202 | { 203 | QuickLookGeneratorPluginType *result; 204 | CFUUIDRef uuid; 205 | 206 | /* If correct type is being requested, allocate an 207 | * instance of kQLGeneratorTypeID and return the IUnknown interface. 208 | */ 209 | if (CFEqual(typeID,kQLGeneratorTypeID)){ 210 | uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID)); 211 | result = AllocQuickLookGeneratorPluginType(uuid); 212 | CFRelease(uuid); 213 | return result; 214 | } 215 | /* If the requested type is incorrect, return NULL. */ 216 | return NULL; 217 | } 218 | 219 | -------------------------------------------------------------------------------- /GeneratePreviewForURL.m: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #import 5 | #import "GNJUnZip.h" 6 | #import "NSString+Additions.h" 7 | 8 | static const NSInteger kMaximumNumberOfLoadingHTML = 10; 9 | static const NSInteger kMaximumNumberOfLoadingImage = 10; 10 | static const NSInteger kLoadAllFiles = -1; 11 | 12 | /* ----------------------------------------------------------------------------- 13 | Generate a preview for file 14 | 15 | This function's job is to create preview for designated file 16 | ----------------------------------------------------------------------------- */ 17 | 18 | OSStatus GeneratePreviewForURL(void *thisInterface, 19 | QLPreviewRequestRef preview, 20 | CFURLRef url, 21 | CFStringRef contentTypeUTI, 22 | CFDictionaryRef options) 23 | { 24 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 25 | 26 | NSInteger maximumNumberOfLoadingHTML = kMaximumNumberOfLoadingHTML; 27 | NSInteger maximumNumberOfLoadingImage = kMaximumNumberOfLoadingImage; 28 | CFBundleRef bundleRef = QLPreviewRequestGetGeneratorBundle(preview); 29 | CFStringRef appId = CFBundleGetIdentifier(bundleRef); 30 | CFStringRef key = (CFStringRef)@"MaximumNumberOfLoadingHTML"; 31 | CFPropertyListRef plistRef = CFPreferencesCopyAppValue(key, appId); 32 | if(plistRef) { 33 | maximumNumberOfLoadingHTML = [(NSNumber *)plistRef integerValue]; 34 | CFRelease(plistRef); 35 | } 36 | key = (CFStringRef)@"MaximumNumberOfLoadingImage"; 37 | plistRef = CFPreferencesCopyAppValue(key, appId); 38 | if(plistRef) { 39 | maximumNumberOfLoadingImage = [(NSNumber *)plistRef integerValue]; 40 | CFRelease(plistRef); 41 | } 42 | 43 | NSString *path = [(NSURL *)url path]; 44 | GNJUnZip *unzip = [[GNJUnZip alloc] initWithZipFile:path]; 45 | 46 | NSCharacterSet *setForTrim = [NSCharacterSet whitespaceAndNewlineCharacterSet]; 47 | 48 | // Get the path of .opf file 49 | NSData *xmlData = [unzip dataWithContentsOfFile:@"META-INF/container.xml"]; 50 | if(!xmlData) { 51 | [unzip release]; 52 | [pool release]; 53 | return noErr; 54 | } 55 | 56 | NSXMLDocument *xmlDoc = [[NSXMLDocument alloc] initWithData:xmlData 57 | options:NSXMLDocumentTidyXML 58 | error:NULL]; 59 | if(!xmlDoc) { 60 | [unzip release]; 61 | [pool release]; 62 | return noErr; 63 | } 64 | 65 | NSString *xpath = @"/container/rootfiles/rootfile/@full-path"; 66 | NSArray *nodes = [xmlDoc nodesForXPath:xpath error:NULL]; 67 | if(![nodes count]) { 68 | NSLog(@"no such nodes for xpath '%@'", xpath); 69 | [xmlDoc release]; 70 | [unzip release]; 71 | [pool release]; 72 | return noErr; 73 | } 74 | 75 | NSXMLNode *fullPathNode = [nodes objectAtIndex:0]; 76 | NSString *fullPathValue =[fullPathNode stringValue]; 77 | NSString *opfFilePath = [fullPathValue stringByTrimmingCharactersInSet:setForTrim]; 78 | opfFilePath = [opfFilePath stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 79 | [xmlDoc release]; 80 | 81 | 82 | xmlData = [unzip dataWithContentsOfFile:opfFilePath]; 83 | if(!xmlData) { 84 | [unzip release]; 85 | [pool release]; 86 | return noErr; 87 | } 88 | 89 | xmlDoc = [[NSXMLDocument alloc] initWithData:xmlData 90 | options:NSXMLDocumentTidyXML 91 | error:NULL]; 92 | if(!xmlDoc) { 93 | [unzip release]; 94 | [pool release]; 95 | return noErr; 96 | } 97 | 98 | // Get EPUB title 99 | NSString *epubTitle = nil; 100 | xpath = @"/package/metadata/*[local-name()='title']"; 101 | nodes = [xmlDoc nodesForXPath:xpath error:NULL]; 102 | if([nodes count]) { 103 | NSXMLNode *node = [nodes objectAtIndex:0]; 104 | epubTitle = [node stringValue]; 105 | } 106 | if([epubTitle length] == 0) epubTitle = [path lastPathComponent]; 107 | 108 | xpath = @"/package/manifest/item"; 109 | nodes = [xmlDoc nodesForXPath:xpath error:NULL]; 110 | if(![nodes count]) { 111 | NSLog(@"no such nodes for xpath '%@'", xpath); 112 | [xmlDoc release]; 113 | [unzip release]; 114 | [pool release]; 115 | return noErr; 116 | } 117 | 118 | NSMutableDictionary *manifest = [NSMutableDictionary dictionary]; 119 | for(NSXMLElement *elem in nodes) { 120 | NSXMLNode *idNode = [elem attributeForName:@"id"]; 121 | NSXMLNode *hrefNode = [elem attributeForName:@"href"]; 122 | NSString *key = [[idNode stringValue] stringByTrimmingCharactersInSet:setForTrim]; 123 | NSString *hrefValue = [[hrefNode stringValue] stringByTrimmingCharactersInSet:setForTrim]; 124 | hrefValue = [hrefValue stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 125 | [manifest setObject:hrefValue forKey:key]; 126 | } 127 | 128 | xpath = @"/package/spine/itemref/@idref"; 129 | nodes = [xmlDoc nodesForXPath:xpath error:NULL]; 130 | if(![nodes count]) { 131 | NSLog(@"no such nodes for xpath '%@'", xpath); 132 | [xmlDoc release]; 133 | [unzip release]; 134 | [pool release]; 135 | return noErr; 136 | } 137 | 138 | NSUInteger numberOfHTML = 0; 139 | NSMutableArray *htmlPaths = [NSMutableArray array]; 140 | NSString *opfBasePath = [opfFilePath stringByDeletingLastPathComponent]; 141 | for(NSXMLNode *node in nodes) { 142 | NSString *idref = [[node stringValue] stringByTrimmingCharactersInSet:setForTrim]; 143 | NSString *hrefValue = [manifest objectForKey:idref]; 144 | if(![hrefValue length]) continue; 145 | NSString *htmlPath = nil; 146 | if([hrefValue isAbsolutePath]) htmlPath = [hrefValue substringFromIndex:1]; 147 | else htmlPath = [opfBasePath stringByAppendingPathComponent:hrefValue]; 148 | htmlPath = [htmlPath stringByForciblyResolvingSymlinksInPath]; 149 | [htmlPaths addObject:htmlPath]; 150 | 151 | if(maximumNumberOfLoadingHTML != kLoadAllFiles && 152 | ++numberOfHTML >= maximumNumberOfLoadingHTML) break; 153 | } 154 | [xmlDoc release]; 155 | 156 | if(![htmlPaths count]) { 157 | [unzip release]; 158 | [pool release]; 159 | return noErr; 160 | } 161 | 162 | // Create an HTML document for output 163 | NSXMLElement *htmlElement = [NSXMLElement elementWithName:@"html"]; 164 | NSXMLElement *headElement = [NSXMLElement elementWithName:@"head"]; 165 | NSXMLElement *metaElement = [NSXMLElement elementWithName:@"meta"]; 166 | NSXMLNode *charSetAttribute = [[[NSXMLNode alloc] initWithKind:NSXMLAttributeKind] autorelease]; 167 | [charSetAttribute setName:@"charset"]; 168 | [charSetAttribute setStringValue:@"utf-8"]; 169 | [metaElement addAttribute:charSetAttribute]; 170 | [headElement addChild:metaElement]; 171 | NSXMLElement *titleElement = [NSXMLElement elementWithName:@"title"]; 172 | [titleElement setStringValue:epubTitle]; 173 | [headElement addChild:titleElement]; 174 | [htmlElement addChild:headElement]; 175 | NSXMLDocument *htmlDocument = [[NSXMLDocument alloc] initWithRootElement:htmlElement]; 176 | 177 | // Combine the data of HTML files. 178 | NSMutableDictionary *attachments = [NSMutableDictionary dictionary]; 179 | for(NSString *htmlPath in htmlPaths) { 180 | NSData *rawHtmlData = [unzip dataWithContentsOfFile:htmlPath]; 181 | if(!rawHtmlData) continue; 182 | xmlDoc = [[NSXMLDocument alloc] initWithData:rawHtmlData 183 | options:NSXMLDocumentTidyXML 184 | error:NULL]; 185 | if(!xmlDoc) continue; 186 | 187 | // Rewrite the paths of embedded image files and css files, 188 | // and then store the data to an attachment dictionary, 189 | if(maximumNumberOfLoadingImage != 0) { 190 | xpath = @"//img/@src" 191 | @"|//*[local-name()='svg']/*[local-name()='image']/@*[local-name()='href']" 192 | @"|//*[local-name()='svg']/*[local-name()='image']/@href" 193 | @"|//*[local-name()='svg']/image/@*[local-name()='href']" 194 | @"|//*[local-name()='svg']/image/@href" 195 | @"|//svg/*[local-name()='image']/@*[local-name()='href']" 196 | @"|//svg/*[local-name()='image']/@href" 197 | @"|//svg/image/@*[local-name()='href']" 198 | @"|//svg/image/@href" 199 | @"|//head/link/@href" 200 | ; 201 | nodes = [xmlDoc nodesForXPath:xpath error:NULL]; 202 | NSString *htmlBasePath = [htmlPath stringByDeletingLastPathComponent]; 203 | NSUInteger numberOfImage = 0; 204 | for(NSXMLNode *node in nodes) { 205 | if(QLPreviewRequestIsCancelled(preview)) { 206 | [htmlDocument release]; 207 | [xmlDoc release]; 208 | [unzip release]; 209 | [pool release]; 210 | return noErr; 211 | } 212 | 213 | NSString *attachmentPath = nil; 214 | NSString *srcValue = [[node stringValue] stringByTrimmingCharactersInSet:setForTrim]; 215 | srcValue = [srcValue stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 216 | if([srcValue isAbsolutePath]) attachmentPath = [srcValue substringFromIndex:1]; 217 | else attachmentPath = [htmlBasePath stringByAppendingPathComponent:srcValue]; 218 | attachmentPath = [attachmentPath stringByForciblyResolvingSymlinksInPath]; 219 | 220 | NSData *attachmentData = [unzip dataWithContentsOfFile:attachmentPath]; 221 | if(!attachmentData) continue; 222 | 223 | [node setStringValue:[@"cid:" stringByAppendingString:attachmentPath]]; 224 | 225 | NSString *key = (NSString *)kQLPreviewPropertyAttachmentDataKey; 226 | NSDictionary *attachment = [NSDictionary dictionaryWithObject:attachmentData 227 | forKey:key]; 228 | [attachments setObject:attachment forKey:attachmentPath]; 229 | 230 | if(maximumNumberOfLoadingImage != kLoadAllFiles && 231 | ++numberOfImage >= maximumNumberOfLoadingImage) break; 232 | } 233 | } 234 | 235 | [[htmlDocument rootElement] addChild:[[[xmlDoc rootElement] copy] autorelease]]; 236 | [xmlDoc release]; 237 | } 238 | 239 | NSDictionary *properties = [NSDictionary dictionaryWithObjectsAndKeys: 240 | @"text/html", 241 | (NSString *)kQLPreviewPropertyMIMETypeKey, 242 | @"UTF-8", 243 | (NSString *)kQLPreviewPropertyTextEncodingNameKey, 244 | attachments, 245 | (NSString *)kQLPreviewPropertyAttachmentsKey, 246 | nil]; 247 | QLPreviewRequestSetDataRepresentation(preview, 248 | (CFDataRef)[htmlDocument XMLData], 249 | kUTTypeHTML, 250 | (CFDictionaryRef)properties); 251 | 252 | [htmlDocument release]; 253 | [unzip release]; 254 | [pool release]; 255 | 256 | return noErr; 257 | } 258 | 259 | void CancelPreviewGeneration(void* thisInterface, QLPreviewRequestRef preview) 260 | { 261 | // implement only if supported 262 | } 263 | -------------------------------------------------------------------------------- /EPUBQLGenerator.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2C05A19C06CAA52B00D84F6F /* GeneratePreviewForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C05A19B06CAA52B00D84F6F /* GeneratePreviewForURL.m */; }; 11 | 61E3BCFB0870B4F2002186A0 /* GenerateThumbnailForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 61E3BCFA0870B4F2002186A0 /* GenerateThumbnailForURL.m */; }; 12 | 8D576312048677EA00EA77CD /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 08FB77B6FE84183AC02AAC07 /* main.c */; settings = {ATTRIBUTES = (); }; }; 13 | 8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */; }; 14 | 8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8D5B49A704867FD3000E48DA /* InfoPlist.strings */; }; 15 | B64106C513D184630034C431 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B64106C413D184630034C431 /* Cocoa.framework */; }; 16 | B64106D613D184920034C431 /* GNJUnZip.h in Headers */ = {isa = PBXBuildFile; fileRef = B64106D413D184920034C431 /* GNJUnZip.h */; }; 17 | B64106D713D184920034C431 /* GNJUnZip.m in Sources */ = {isa = PBXBuildFile; fileRef = B64106D513D184920034C431 /* GNJUnZip.m */; }; 18 | B64106DD13D1849C0034C431 /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = B64106D913D1849C0034C431 /* ioapi.c */; }; 19 | B64106DE13D1849C0034C431 /* ioapi.h in Headers */ = {isa = PBXBuildFile; fileRef = B64106DA13D1849C0034C431 /* ioapi.h */; }; 20 | B64106DF13D1849C0034C431 /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = B64106DB13D1849C0034C431 /* unzip.c */; }; 21 | B64106E013D1849C0034C431 /* unzip.h in Headers */ = {isa = PBXBuildFile; fileRef = B64106DC13D1849C0034C431 /* unzip.h */; }; 22 | B64106EA13D184F20034C431 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B64106E913D184F20034C431 /* libz.dylib */; }; 23 | B648348416EC884D00CED886 /* NSString+Additions.h in Headers */ = {isa = PBXBuildFile; fileRef = B648348216EC884D00CED886 /* NSString+Additions.h */; }; 24 | B648348516EC884D00CED886 /* NSString+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = B648348316EC884D00CED886 /* NSString+Additions.m */; }; 25 | C86B05270671AA6E00DD9006 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C86B05260671AA6E00DD9006 /* CoreServices.framework */; }; 26 | F28CFBFD0A3EC0AF000ABFF5 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F28CFBFC0A3EC0AF000ABFF5 /* ApplicationServices.framework */; }; 27 | F28CFC030A3EC0C6000ABFF5 /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F28CFC020A3EC0C6000ABFF5 /* QuickLook.framework */; }; 28 | /* End PBXBuildFile section */ 29 | 30 | /* Begin PBXFileReference section */ 31 | 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 32 | 08FB77B6FE84183AC02AAC07 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; 33 | 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; 34 | 2C05A19B06CAA52B00D84F6F /* GeneratePreviewForURL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratePreviewForURL.m; sourceTree = ""; }; 35 | 61E3BCFA0870B4F2002186A0 /* GenerateThumbnailForURL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GenerateThumbnailForURL.m; sourceTree = ""; }; 36 | 8D576316048677EA00EA77CD /* EPUBQLGenerator.qlgenerator */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EPUBQLGenerator.qlgenerator; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | 8D576317048677EA00EA77CD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 38 | B64106C413D184630034C431 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 39 | B64106D413D184920034C431 /* GNJUnZip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNJUnZip.h; sourceTree = ""; }; 40 | B64106D513D184920034C431 /* GNJUnZip.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNJUnZip.m; sourceTree = ""; }; 41 | B64106D913D1849C0034C431 /* ioapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioapi.c; sourceTree = ""; }; 42 | B64106DA13D1849C0034C431 /* ioapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ioapi.h; sourceTree = ""; }; 43 | B64106DB13D1849C0034C431 /* unzip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unzip.c; sourceTree = ""; }; 44 | B64106DC13D1849C0034C431 /* unzip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unzip.h; sourceTree = ""; }; 45 | B64106E913D184F20034C431 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; 46 | B648348216EC884D00CED886 /* NSString+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+Additions.h"; sourceTree = ""; }; 47 | B648348316EC884D00CED886 /* NSString+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+Additions.m"; sourceTree = ""; }; 48 | B67F4CC813D3557D00BF6948 /* README.rst */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.rst; sourceTree = ""; }; 49 | C86B05260671AA6E00DD9006 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = ""; }; 50 | F28CFBFC0A3EC0AF000ABFF5 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = ""; }; 51 | F28CFC020A3EC0C6000ABFF5 /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = /System/Library/Frameworks/QuickLook.framework; sourceTree = ""; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | 8D576313048677EA00EA77CD /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | 8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */, 60 | C86B05270671AA6E00DD9006 /* CoreServices.framework in Frameworks */, 61 | F28CFBFD0A3EC0AF000ABFF5 /* ApplicationServices.framework in Frameworks */, 62 | F28CFC030A3EC0C6000ABFF5 /* QuickLook.framework in Frameworks */, 63 | B64106C513D184630034C431 /* Cocoa.framework in Frameworks */, 64 | B64106EA13D184F20034C431 /* libz.dylib in Frameworks */, 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | /* End PBXFrameworksBuildPhase section */ 69 | 70 | /* Begin PBXGroup section */ 71 | 089C166AFE841209C02AAC07 /* EPUBQL */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | 08FB77AFFE84173DC02AAC07 /* Source */, 75 | 089C167CFE841241C02AAC07 /* Resources */, 76 | 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */, 77 | 19C28FB6FE9D52B211CA2CBB /* Products */, 78 | ); 79 | name = EPUBQL; 80 | sourceTree = ""; 81 | }; 82 | 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | F28CFC020A3EC0C6000ABFF5 /* QuickLook.framework */, 86 | F28CFBFC0A3EC0AF000ABFF5 /* ApplicationServices.framework */, 87 | C86B05260671AA6E00DD9006 /* CoreServices.framework */, 88 | 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */, 89 | B64106C413D184630034C431 /* Cocoa.framework */, 90 | B64106E913D184F20034C431 /* libz.dylib */, 91 | ); 92 | name = "External Frameworks and Libraries"; 93 | sourceTree = ""; 94 | }; 95 | 089C167CFE841241C02AAC07 /* Resources */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 8D576317048677EA00EA77CD /* Info.plist */, 99 | 8D5B49A704867FD3000E48DA /* InfoPlist.strings */, 100 | B67F4CC813D3557D00BF6948 /* README.rst */, 101 | ); 102 | name = Resources; 103 | sourceTree = ""; 104 | }; 105 | 08FB77AFFE84173DC02AAC07 /* Source */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | B64106D813D1849C0034C431 /* minizip */, 109 | 61E3BCFA0870B4F2002186A0 /* GenerateThumbnailForURL.m */, 110 | 2C05A19B06CAA52B00D84F6F /* GeneratePreviewForURL.m */, 111 | B64106D413D184920034C431 /* GNJUnZip.h */, 112 | B64106D513D184920034C431 /* GNJUnZip.m */, 113 | B648348216EC884D00CED886 /* NSString+Additions.h */, 114 | B648348316EC884D00CED886 /* NSString+Additions.m */, 115 | 08FB77B6FE84183AC02AAC07 /* main.c */, 116 | ); 117 | name = Source; 118 | sourceTree = ""; 119 | }; 120 | 19C28FB6FE9D52B211CA2CBB /* Products */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 8D576316048677EA00EA77CD /* EPUBQLGenerator.qlgenerator */, 124 | ); 125 | name = Products; 126 | sourceTree = ""; 127 | }; 128 | B64106D813D1849C0034C431 /* minizip */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | B64106D913D1849C0034C431 /* ioapi.c */, 132 | B64106DA13D1849C0034C431 /* ioapi.h */, 133 | B64106DB13D1849C0034C431 /* unzip.c */, 134 | B64106DC13D1849C0034C431 /* unzip.h */, 135 | ); 136 | path = minizip; 137 | sourceTree = ""; 138 | }; 139 | /* End PBXGroup section */ 140 | 141 | /* Begin PBXHeadersBuildPhase section */ 142 | 8D57630E048677EA00EA77CD /* Headers */ = { 143 | isa = PBXHeadersBuildPhase; 144 | buildActionMask = 2147483647; 145 | files = ( 146 | B64106D613D184920034C431 /* GNJUnZip.h in Headers */, 147 | B64106DE13D1849C0034C431 /* ioapi.h in Headers */, 148 | B64106E013D1849C0034C431 /* unzip.h in Headers */, 149 | B648348416EC884D00CED886 /* NSString+Additions.h in Headers */, 150 | ); 151 | runOnlyForDeploymentPostprocessing = 0; 152 | }; 153 | /* End PBXHeadersBuildPhase section */ 154 | 155 | /* Begin PBXNativeTarget section */ 156 | 8D57630D048677EA00EA77CD /* EPUBQLGenerator */ = { 157 | isa = PBXNativeTarget; 158 | buildConfigurationList = 2CA3261E0896AD4900168862 /* Build configuration list for PBXNativeTarget "EPUBQLGenerator" */; 159 | buildPhases = ( 160 | 8D57630E048677EA00EA77CD /* Headers */, 161 | 8D57630F048677EA00EA77CD /* Resources */, 162 | 8D576311048677EA00EA77CD /* Sources */, 163 | 8D576313048677EA00EA77CD /* Frameworks */, 164 | 8D576315048677EA00EA77CD /* Rez */, 165 | ); 166 | buildRules = ( 167 | ); 168 | dependencies = ( 169 | ); 170 | name = EPUBQLGenerator; 171 | productInstallPath = /Library/QuickLook; 172 | productName = EPUBQL; 173 | productReference = 8D576316048677EA00EA77CD /* EPUBQLGenerator.qlgenerator */; 174 | productType = "com.apple.product-type.bundle"; 175 | }; 176 | /* End PBXNativeTarget section */ 177 | 178 | /* Begin PBXProject section */ 179 | 089C1669FE841209C02AAC07 /* Project object */ = { 180 | isa = PBXProject; 181 | attributes = { 182 | LastUpgradeCheck = 0430; 183 | }; 184 | buildConfigurationList = 2CA326220896AD4900168862 /* Build configuration list for PBXProject "EPUBQLGenerator" */; 185 | compatibilityVersion = "Xcode 3.2"; 186 | developmentRegion = English; 187 | hasScannedForEncodings = 1; 188 | knownRegions = ( 189 | English, 190 | Japanese, 191 | French, 192 | German, 193 | ); 194 | mainGroup = 089C166AFE841209C02AAC07 /* EPUBQL */; 195 | projectDirPath = ""; 196 | projectRoot = ""; 197 | targets = ( 198 | 8D57630D048677EA00EA77CD /* EPUBQLGenerator */, 199 | ); 200 | }; 201 | /* End PBXProject section */ 202 | 203 | /* Begin PBXResourcesBuildPhase section */ 204 | 8D57630F048677EA00EA77CD /* Resources */ = { 205 | isa = PBXResourcesBuildPhase; 206 | buildActionMask = 2147483647; 207 | files = ( 208 | 8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXResourcesBuildPhase section */ 213 | 214 | /* Begin PBXRezBuildPhase section */ 215 | 8D576315048677EA00EA77CD /* Rez */ = { 216 | isa = PBXRezBuildPhase; 217 | buildActionMask = 2147483647; 218 | files = ( 219 | ); 220 | runOnlyForDeploymentPostprocessing = 0; 221 | }; 222 | /* End PBXRezBuildPhase section */ 223 | 224 | /* Begin PBXSourcesBuildPhase section */ 225 | 8D576311048677EA00EA77CD /* Sources */ = { 226 | isa = PBXSourcesBuildPhase; 227 | buildActionMask = 2147483647; 228 | files = ( 229 | 8D576312048677EA00EA77CD /* main.c in Sources */, 230 | 2C05A19C06CAA52B00D84F6F /* GeneratePreviewForURL.m in Sources */, 231 | 61E3BCFB0870B4F2002186A0 /* GenerateThumbnailForURL.m in Sources */, 232 | B64106D713D184920034C431 /* GNJUnZip.m in Sources */, 233 | B64106DD13D1849C0034C431 /* ioapi.c in Sources */, 234 | B64106DF13D1849C0034C431 /* unzip.c in Sources */, 235 | B648348516EC884D00CED886 /* NSString+Additions.m in Sources */, 236 | ); 237 | runOnlyForDeploymentPostprocessing = 0; 238 | }; 239 | /* End PBXSourcesBuildPhase section */ 240 | 241 | /* Begin PBXVariantGroup section */ 242 | 8D5B49A704867FD3000E48DA /* InfoPlist.strings */ = { 243 | isa = PBXVariantGroup; 244 | children = ( 245 | 089C167EFE841241C02AAC07 /* English */, 246 | ); 247 | name = InfoPlist.strings; 248 | sourceTree = ""; 249 | }; 250 | /* End PBXVariantGroup section */ 251 | 252 | /* Begin XCBuildConfiguration section */ 253 | 2CA3261F0896AD4900168862 /* Debug */ = { 254 | isa = XCBuildConfiguration; 255 | buildSettings = { 256 | COPY_PHASE_STRIP = NO; 257 | GCC_DYNAMIC_NO_PIC = NO; 258 | GCC_MODEL_TUNING = G5; 259 | GCC_OPTIMIZATION_LEVEL = 0; 260 | GCC_PRECOMPILE_PREFIX_HEADER = NO; 261 | INFOPLIST_FILE = Info.plist; 262 | INSTALL_PATH = /Library/QuickLook; 263 | PRODUCT_NAME = EPUBQLGenerator; 264 | WRAPPER_EXTENSION = qlgenerator; 265 | }; 266 | name = Debug; 267 | }; 268 | 2CA326200896AD4900168862 /* Release */ = { 269 | isa = XCBuildConfiguration; 270 | buildSettings = { 271 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 272 | GCC_MODEL_TUNING = G5; 273 | GCC_PRECOMPILE_PREFIX_HEADER = NO; 274 | INFOPLIST_FILE = Info.plist; 275 | INSTALL_PATH = /Library/QuickLook; 276 | PRODUCT_NAME = EPUBQLGenerator; 277 | WRAPPER_EXTENSION = qlgenerator; 278 | }; 279 | name = Release; 280 | }; 281 | 2CA326230896AD4900168862 /* Debug */ = { 282 | isa = XCBuildConfiguration; 283 | buildSettings = { 284 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 285 | CURRENT_PROJECT_VERSION = 7; 286 | GCC_C_LANGUAGE_STANDARD = gnu99; 287 | GCC_PREPROCESSOR_DEFINITIONS = USE_FILE32API; 288 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 289 | GCC_WARN_UNUSED_VARIABLE = YES; 290 | MACOSX_DEPLOYMENT_TARGET = 10.6; 291 | ONLY_ACTIVE_ARCH = YES; 292 | SDKROOT = macosx; 293 | STRINGS_FILE_OUTPUT_ENCODING = "UTF-8"; 294 | VERSIONING_SYSTEM = "apple-generic"; 295 | }; 296 | name = Debug; 297 | }; 298 | 2CA326240896AD4900168862 /* Release */ = { 299 | isa = XCBuildConfiguration; 300 | buildSettings = { 301 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 302 | CURRENT_PROJECT_VERSION = 7; 303 | GCC_C_LANGUAGE_STANDARD = gnu99; 304 | GCC_PREPROCESSOR_DEFINITIONS = USE_FILE32API; 305 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 306 | GCC_WARN_UNUSED_VARIABLE = YES; 307 | MACOSX_DEPLOYMENT_TARGET = 10.6; 308 | SDKROOT = macosx; 309 | STRINGS_FILE_OUTPUT_ENCODING = "UTF-8"; 310 | VERSIONING_SYSTEM = "apple-generic"; 311 | }; 312 | name = Release; 313 | }; 314 | /* End XCBuildConfiguration section */ 315 | 316 | /* Begin XCConfigurationList section */ 317 | 2CA3261E0896AD4900168862 /* Build configuration list for PBXNativeTarget "EPUBQLGenerator" */ = { 318 | isa = XCConfigurationList; 319 | buildConfigurations = ( 320 | 2CA3261F0896AD4900168862 /* Debug */, 321 | 2CA326200896AD4900168862 /* Release */, 322 | ); 323 | defaultConfigurationIsVisible = 0; 324 | defaultConfigurationName = Release; 325 | }; 326 | 2CA326220896AD4900168862 /* Build configuration list for PBXProject "EPUBQLGenerator" */ = { 327 | isa = XCConfigurationList; 328 | buildConfigurations = ( 329 | 2CA326230896AD4900168862 /* Debug */, 330 | 2CA326240896AD4900168862 /* Release */, 331 | ); 332 | defaultConfigurationIsVisible = 0; 333 | defaultConfigurationName = Release; 334 | }; 335 | /* End XCConfigurationList section */ 336 | }; 337 | rootObject = 089C1669FE841209C02AAC07 /* Project object */; 338 | } 339 | -------------------------------------------------------------------------------- /minizip/unzip.h: -------------------------------------------------------------------------------- 1 | /* unzip.h -- IO for uncompress .zip files using zlib 2 | Version 1.1, February 14h, 2010 3 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) 4 | 5 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) 6 | 7 | Modifications of Unzip for Zip64 8 | Copyright (C) 2007-2008 Even Rouault 9 | 10 | Modifications for Zip64 support on both zip and unzip 11 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) 12 | 13 | For more info read MiniZip_info.txt 14 | 15 | --------------------------------------------------------------------------------- 16 | 17 | Condition of use and distribution are the same than zlib : 18 | 19 | This software is provided 'as-is', without any express or implied 20 | warranty. In no event will the authors be held liable for any damages 21 | arising from the use of this software. 22 | 23 | Permission is granted to anyone to use this software for any purpose, 24 | including commercial applications, and to alter it and redistribute it 25 | freely, subject to the following restrictions: 26 | 27 | 1. The origin of this software must not be misrepresented; you must not 28 | claim that you wrote the original software. If you use this software 29 | in a product, an acknowledgment in the product documentation would be 30 | appreciated but is not required. 31 | 2. Altered source versions must be plainly marked as such, and must not be 32 | misrepresented as being the original software. 33 | 3. This notice may not be removed or altered from any source distribution. 34 | 35 | --------------------------------------------------------------------------------- 36 | 37 | Changes 38 | 39 | See header of unzip64.c 40 | 41 | */ 42 | 43 | #ifndef _unz64_H 44 | #define _unz64_H 45 | 46 | #ifdef __cplusplus 47 | extern "C" { 48 | #endif 49 | 50 | #ifndef _ZLIB_H 51 | #include "zlib.h" 52 | #endif 53 | 54 | #ifndef _ZLIBIOAPI_H 55 | #include "ioapi.h" 56 | #endif 57 | 58 | #ifdef HAVE_BZIP2 59 | #include "bzlib.h" 60 | #endif 61 | 62 | #define Z_BZIP2ED 12 63 | 64 | #if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) 65 | /* like the STRICT of WIN32, we define a pointer that cannot be converted 66 | from (void*) without cast */ 67 | typedef struct TagunzFile__ { int unused; } unzFile__; 68 | typedef unzFile__ *unzFile; 69 | #else 70 | typedef voidp unzFile; 71 | #endif 72 | 73 | 74 | #define UNZ_OK (0) 75 | #define UNZ_END_OF_LIST_OF_FILE (-100) 76 | #define UNZ_ERRNO (Z_ERRNO) 77 | #define UNZ_EOF (0) 78 | #define UNZ_PARAMERROR (-102) 79 | #define UNZ_BADZIPFILE (-103) 80 | #define UNZ_INTERNALERROR (-104) 81 | #define UNZ_CRCERROR (-105) 82 | 83 | /* tm_unz contain date/time info */ 84 | typedef struct tm_unz_s 85 | { 86 | uInt tm_sec; /* seconds after the minute - [0,59] */ 87 | uInt tm_min; /* minutes after the hour - [0,59] */ 88 | uInt tm_hour; /* hours since midnight - [0,23] */ 89 | uInt tm_mday; /* day of the month - [1,31] */ 90 | uInt tm_mon; /* months since January - [0,11] */ 91 | uInt tm_year; /* years - [1980..2044] */ 92 | } tm_unz; 93 | 94 | /* unz_global_info structure contain global data about the ZIPfile 95 | These data comes from the end of central dir */ 96 | typedef struct unz_global_info64_s 97 | { 98 | ZPOS64_T number_entry; /* total number of entries in 99 | the central dir on this disk */ 100 | uLong size_comment; /* size of the global comment of the zipfile */ 101 | } unz_global_info64; 102 | 103 | typedef struct unz_global_info_s 104 | { 105 | uLong number_entry; /* total number of entries in 106 | the central dir on this disk */ 107 | uLong size_comment; /* size of the global comment of the zipfile */ 108 | } unz_global_info; 109 | 110 | /* unz_file_info contain information about a file in the zipfile */ 111 | typedef struct unz_file_info64_s 112 | { 113 | uLong version; /* version made by 2 bytes */ 114 | uLong version_needed; /* version needed to extract 2 bytes */ 115 | uLong flag; /* general purpose bit flag 2 bytes */ 116 | uLong compression_method; /* compression method 2 bytes */ 117 | uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ 118 | uLong crc; /* crc-32 4 bytes */ 119 | ZPOS64_T compressed_size; /* compressed size 8 bytes */ 120 | ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ 121 | uLong size_filename; /* filename length 2 bytes */ 122 | uLong size_file_extra; /* extra field length 2 bytes */ 123 | uLong size_file_comment; /* file comment length 2 bytes */ 124 | 125 | uLong disk_num_start; /* disk number start 2 bytes */ 126 | uLong internal_fa; /* internal file attributes 2 bytes */ 127 | uLong external_fa; /* external file attributes 4 bytes */ 128 | 129 | tm_unz tmu_date; 130 | } unz_file_info64; 131 | 132 | typedef struct unz_file_info_s 133 | { 134 | uLong version; /* version made by 2 bytes */ 135 | uLong version_needed; /* version needed to extract 2 bytes */ 136 | uLong flag; /* general purpose bit flag 2 bytes */ 137 | uLong compression_method; /* compression method 2 bytes */ 138 | uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ 139 | uLong crc; /* crc-32 4 bytes */ 140 | uLong compressed_size; /* compressed size 4 bytes */ 141 | uLong uncompressed_size; /* uncompressed size 4 bytes */ 142 | uLong size_filename; /* filename length 2 bytes */ 143 | uLong size_file_extra; /* extra field length 2 bytes */ 144 | uLong size_file_comment; /* file comment length 2 bytes */ 145 | 146 | uLong disk_num_start; /* disk number start 2 bytes */ 147 | uLong internal_fa; /* internal file attributes 2 bytes */ 148 | uLong external_fa; /* external file attributes 4 bytes */ 149 | 150 | tm_unz tmu_date; 151 | } unz_file_info; 152 | 153 | extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, 154 | const char* fileName2, 155 | int iCaseSensitivity)); 156 | /* 157 | Compare two filename (fileName1,fileName2). 158 | If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) 159 | If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi 160 | or strcasecmp) 161 | If iCaseSenisivity = 0, case sensitivity is defaut of your operating system 162 | (like 1 on Unix, 2 on Windows) 163 | */ 164 | 165 | 166 | extern unzFile ZEXPORT unzOpen OF((const char *path)); 167 | extern unzFile ZEXPORT unzOpen64 OF((const void *path)); 168 | /* 169 | Open a Zip file. path contain the full pathname (by example, 170 | on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer 171 | "zlib/zlib113.zip". 172 | If the zipfile cannot be opened (file don't exist or in not valid), the 173 | return value is NULL. 174 | Else, the return value is a unzFile Handle, usable with other function 175 | of this unzip package. 176 | the "64" function take a const void* pointer, because the path is just the 177 | value passed to the open64_file_func callback. 178 | Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path 179 | is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* 180 | does not describe the reality 181 | */ 182 | 183 | 184 | extern unzFile ZEXPORT unzOpen2 OF((const char *path, 185 | zlib_filefunc_def* pzlib_filefunc_def)); 186 | /* 187 | Open a Zip file, like unzOpen, but provide a set of file low level API 188 | for read/write the zip file (see ioapi.h) 189 | */ 190 | 191 | extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, 192 | zlib_filefunc64_def* pzlib_filefunc_def)); 193 | /* 194 | Open a Zip file, like unz64Open, but provide a set of file low level API 195 | for read/write the zip file (see ioapi.h) 196 | */ 197 | 198 | extern int ZEXPORT unzClose OF((unzFile file)); 199 | /* 200 | Close a ZipFile opened with unzipOpen. 201 | If there is files inside the .Zip opened with unzOpenCurrentFile (see later), 202 | these files MUST be closed with unzipCloseCurrentFile before call unzipClose. 203 | return UNZ_OK if there is no problem. */ 204 | 205 | extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, 206 | unz_global_info *pglobal_info)); 207 | 208 | extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, 209 | unz_global_info64 *pglobal_info)); 210 | /* 211 | Write info about the ZipFile in the *pglobal_info structure. 212 | No preparation of the structure is needed 213 | return UNZ_OK if there is no problem. */ 214 | 215 | 216 | extern int ZEXPORT unzGetGlobalComment OF((unzFile file, 217 | char *szComment, 218 | uLong uSizeBuf)); 219 | /* 220 | Get the global comment string of the ZipFile, in the szComment buffer. 221 | uSizeBuf is the size of the szComment buffer. 222 | return the number of byte copied or an error code <0 223 | */ 224 | 225 | 226 | /***************************************************************************/ 227 | /* Unzip package allow you browse the directory of the zipfile */ 228 | 229 | extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); 230 | /* 231 | Set the current file of the zipfile to the first file. 232 | return UNZ_OK if there is no problem 233 | */ 234 | 235 | extern int ZEXPORT unzGoToNextFile OF((unzFile file)); 236 | /* 237 | Set the current file of the zipfile to the next file. 238 | return UNZ_OK if there is no problem 239 | return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. 240 | */ 241 | 242 | extern int ZEXPORT unzLocateFile OF((unzFile file, 243 | const char *szFileName, 244 | int iCaseSensitivity)); 245 | /* 246 | Try locate the file szFileName in the zipfile. 247 | For the iCaseSensitivity signification, see unzStringFileNameCompare 248 | 249 | return value : 250 | UNZ_OK if the file is found. It becomes the current file. 251 | UNZ_END_OF_LIST_OF_FILE if the file is not found 252 | */ 253 | 254 | 255 | /* ****************************************** */ 256 | /* Ryan supplied functions */ 257 | /* unz_file_info contain information about a file in the zipfile */ 258 | typedef struct unz_file_pos_s 259 | { 260 | uLong pos_in_zip_directory; /* offset in zip file directory */ 261 | uLong num_of_file; /* # of file */ 262 | } unz_file_pos; 263 | 264 | extern int ZEXPORT unzGetFilePos( 265 | unzFile file, 266 | unz_file_pos* file_pos); 267 | 268 | extern int ZEXPORT unzGoToFilePos( 269 | unzFile file, 270 | unz_file_pos* file_pos); 271 | 272 | typedef struct unz64_file_pos_s 273 | { 274 | ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ 275 | ZPOS64_T num_of_file; /* # of file */ 276 | } unz64_file_pos; 277 | 278 | extern int ZEXPORT unzGetFilePos64( 279 | unzFile file, 280 | unz64_file_pos* file_pos); 281 | 282 | extern int ZEXPORT unzGoToFilePos64( 283 | unzFile file, 284 | const unz64_file_pos* file_pos); 285 | 286 | /* ****************************************** */ 287 | 288 | extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, 289 | unz_file_info64 *pfile_info, 290 | char *szFileName, 291 | uLong fileNameBufferSize, 292 | void *extraField, 293 | uLong extraFieldBufferSize, 294 | char *szComment, 295 | uLong commentBufferSize)); 296 | 297 | extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, 298 | unz_file_info *pfile_info, 299 | char *szFileName, 300 | uLong fileNameBufferSize, 301 | void *extraField, 302 | uLong extraFieldBufferSize, 303 | char *szComment, 304 | uLong commentBufferSize)); 305 | /* 306 | Get Info about the current file 307 | if pfile_info!=NULL, the *pfile_info structure will contain somes info about 308 | the current file 309 | if szFileName!=NULL, the filemane string will be copied in szFileName 310 | (fileNameBufferSize is the size of the buffer) 311 | if extraField!=NULL, the extra field information will be copied in extraField 312 | (extraFieldBufferSize is the size of the buffer). 313 | This is the Central-header version of the extra field 314 | if szComment!=NULL, the comment string of the file will be copied in szComment 315 | (commentBufferSize is the size of the buffer) 316 | */ 317 | 318 | 319 | /** Addition for GDAL : START */ 320 | 321 | extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); 322 | 323 | /** Addition for GDAL : END */ 324 | 325 | 326 | /***************************************************************************/ 327 | /* for reading the content of the current zipfile, you can open it, read data 328 | from it, and close it (you can close it before reading all the file) 329 | */ 330 | 331 | extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); 332 | /* 333 | Open for reading data the current file in the zipfile. 334 | If there is no error, the return value is UNZ_OK. 335 | */ 336 | 337 | extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, 338 | const char* password)); 339 | /* 340 | Open for reading data the current file in the zipfile. 341 | password is a crypting password 342 | If there is no error, the return value is UNZ_OK. 343 | */ 344 | 345 | extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, 346 | int* method, 347 | int* level, 348 | int raw)); 349 | /* 350 | Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) 351 | if raw==1 352 | *method will receive method of compression, *level will receive level of 353 | compression 354 | note : you can set level parameter as NULL (if you did not want known level, 355 | but you CANNOT set method parameter as NULL 356 | */ 357 | 358 | extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, 359 | int* method, 360 | int* level, 361 | int raw, 362 | const char* password)); 363 | /* 364 | Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) 365 | if raw==1 366 | *method will receive method of compression, *level will receive level of 367 | compression 368 | note : you can set level parameter as NULL (if you did not want known level, 369 | but you CANNOT set method parameter as NULL 370 | */ 371 | 372 | 373 | extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); 374 | /* 375 | Close the file in zip opened with unzOpenCurrentFile 376 | Return UNZ_CRCERROR if all the file was read but the CRC is not good 377 | */ 378 | 379 | extern int ZEXPORT unzReadCurrentFile OF((unzFile file, 380 | voidp buf, 381 | unsigned len)); 382 | /* 383 | Read bytes from the current file (opened by unzOpenCurrentFile) 384 | buf contain buffer where data must be copied 385 | len the size of buf. 386 | 387 | return the number of byte copied if somes bytes are copied 388 | return 0 if the end of file was reached 389 | return <0 with error code if there is an error 390 | (UNZ_ERRNO for IO error, or zLib error for uncompress error) 391 | */ 392 | 393 | extern z_off_t ZEXPORT unztell OF((unzFile file)); 394 | 395 | extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); 396 | /* 397 | Give the current position in uncompressed data 398 | */ 399 | 400 | extern int ZEXPORT unzeof OF((unzFile file)); 401 | /* 402 | return 1 if the end of file was reached, 0 elsewhere 403 | */ 404 | 405 | extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, 406 | voidp buf, 407 | unsigned len)); 408 | /* 409 | Read extra field from the current file (opened by unzOpenCurrentFile) 410 | This is the local-header version of the extra field (sometimes, there is 411 | more info in the local-header version than in the central-header) 412 | 413 | if buf==NULL, it return the size of the local extra field 414 | 415 | if buf!=NULL, len is the size of the buffer, the extra header is copied in 416 | buf. 417 | the return value is the number of bytes copied in buf, or (if <0) 418 | the error code 419 | */ 420 | 421 | /***************************************************************************/ 422 | 423 | /* Get the current file offset */ 424 | extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); 425 | extern uLong ZEXPORT unzGetOffset (unzFile file); 426 | 427 | /* Set the current file offset */ 428 | extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); 429 | extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); 430 | 431 | 432 | 433 | #ifdef __cplusplus 434 | } 435 | #endif 436 | 437 | #endif /* _unz64_H */ 438 | -------------------------------------------------------------------------------- /minizip/unzip.c: -------------------------------------------------------------------------------- 1 | /* unzip.c -- IO for uncompress .zip files using zlib 2 | Version 1.1, February 14h, 2010 3 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) 4 | 5 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) 6 | 7 | Modifications of Unzip for Zip64 8 | Copyright (C) 2007-2008 Even Rouault 9 | 10 | Modifications for Zip64 support on both zip and unzip 11 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) 12 | 13 | For more info read MiniZip_info.txt 14 | 15 | 16 | ------------------------------------------------------------------------------------ 17 | Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of 18 | compatibility with older software. The following is from the original crypt.c. 19 | Code woven in by Terry Thorsen 1/2003. 20 | 21 | Copyright (c) 1990-2000 Info-ZIP. All rights reserved. 22 | 23 | See the accompanying file LICENSE, version 2000-Apr-09 or later 24 | (the contents of which are also included in zip.h) for terms of use. 25 | If, for some reason, all these files are missing, the Info-ZIP license 26 | also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html 27 | 28 | crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] 29 | 30 | The encryption/decryption parts of this source code (as opposed to the 31 | non-echoing password parts) were originally written in Europe. The 32 | whole source package can be freely distributed, including from the USA. 33 | (Prior to January 2000, re-export from the US was a violation of US law.) 34 | 35 | This encryption code is a direct transcription of the algorithm from 36 | Roger Schlafly, described by Phil Katz in the file appnote.txt. This 37 | file (appnote.txt) is distributed with the PKZIP program (even in the 38 | version without encryption capabilities). 39 | 40 | ------------------------------------------------------------------------------------ 41 | 42 | Changes in unzip.c 43 | 44 | 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos 45 | 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* 46 | 2007-2008 - Even Rouault - Remove old C style function prototypes 47 | 2007-2008 - Even Rouault - Add unzip support for ZIP64 48 | 49 | Copyright (C) 2007-2008 Even Rouault 50 | 51 | 52 | Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). 53 | Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G 54 | should only read the compressed/uncompressed size from the Zip64 format if 55 | the size from normal header was 0xFFFFFFFF 56 | Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant 57 | Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) 58 | Patch created by Daniel Borca 59 | 60 | Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer 61 | 62 | Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson 63 | 64 | */ 65 | 66 | 67 | #include 68 | #include 69 | #include 70 | 71 | #ifndef NOUNCRYPT 72 | #define NOUNCRYPT 73 | #endif 74 | 75 | #include "zlib.h" 76 | #include "unzip.h" 77 | 78 | #ifdef STDC 79 | # include 80 | # include 81 | # include 82 | #endif 83 | #ifdef NO_ERRNO_H 84 | extern int errno; 85 | #else 86 | # include 87 | #endif 88 | 89 | 90 | #ifndef local 91 | # define local static 92 | #endif 93 | /* compile with -Dlocal if your debugger can't find static symbols */ 94 | 95 | 96 | #ifndef CASESENSITIVITYDEFAULT_NO 97 | # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) 98 | # define CASESENSITIVITYDEFAULT_NO 99 | # endif 100 | #endif 101 | 102 | 103 | #ifndef UNZ_BUFSIZE 104 | #define UNZ_BUFSIZE (16384) 105 | #endif 106 | 107 | #ifndef UNZ_MAXFILENAMEINZIP 108 | #define UNZ_MAXFILENAMEINZIP (256) 109 | #endif 110 | 111 | #ifndef ALLOC 112 | # define ALLOC(size) (malloc(size)) 113 | #endif 114 | #ifndef TRYFREE 115 | # define TRYFREE(p) {if (p) free(p);} 116 | #endif 117 | 118 | #define SIZECENTRALDIRITEM (0x2e) 119 | #define SIZEZIPLOCALHEADER (0x1e) 120 | 121 | 122 | const char unz_copyright[] = 123 | " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; 124 | 125 | /* unz_file_info_interntal contain internal info about a file in zipfile*/ 126 | typedef struct unz_file_info64_internal_s 127 | { 128 | ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ 129 | } unz_file_info64_internal; 130 | 131 | 132 | /* file_in_zip_read_info_s contain internal information about a file in zipfile, 133 | when reading and decompress it */ 134 | typedef struct 135 | { 136 | char *read_buffer; /* internal buffer for compressed data */ 137 | z_stream stream; /* zLib stream structure for inflate */ 138 | 139 | #ifdef HAVE_BZIP2 140 | bz_stream bstream; /* bzLib stream structure for bziped */ 141 | #endif 142 | 143 | ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ 144 | uLong stream_initialised; /* flag set if stream structure is initialised*/ 145 | 146 | ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ 147 | uInt size_local_extrafield;/* size of the local extra field */ 148 | ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ 149 | ZPOS64_T total_out_64; 150 | 151 | uLong crc32; /* crc32 of all data uncompressed */ 152 | uLong crc32_wait; /* crc32 we must obtain after decompress all */ 153 | ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ 154 | ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ 155 | zlib_filefunc64_32_def z_filefunc; 156 | voidpf filestream; /* io structore of the zipfile */ 157 | uLong compression_method; /* compression method (0==store) */ 158 | ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ 159 | int raw; 160 | } file_in_zip64_read_info_s; 161 | 162 | 163 | /* unz64_s contain internal information about the zipfile 164 | */ 165 | typedef struct 166 | { 167 | zlib_filefunc64_32_def z_filefunc; 168 | int is64bitOpenFunction; 169 | voidpf filestream; /* io structore of the zipfile */ 170 | unz_global_info64 gi; /* public global information */ 171 | ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ 172 | ZPOS64_T num_file; /* number of the current file in the zipfile*/ 173 | ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ 174 | ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ 175 | ZPOS64_T central_pos; /* position of the beginning of the central dir*/ 176 | 177 | ZPOS64_T size_central_dir; /* size of the central directory */ 178 | ZPOS64_T offset_central_dir; /* offset of start of central directory with 179 | respect to the starting disk number */ 180 | 181 | unz_file_info64 cur_file_info; /* public info about the current file in zip*/ 182 | unz_file_info64_internal cur_file_info_internal; /* private info about it*/ 183 | file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current 184 | file if we are decompressing it */ 185 | int encrypted; 186 | 187 | int isZip64; 188 | 189 | # ifndef NOUNCRYPT 190 | unsigned long keys[3]; /* keys defining the pseudo-random sequence */ 191 | const unsigned long* pcrc_32_tab; 192 | # endif 193 | } unz64_s; 194 | 195 | 196 | #ifndef NOUNCRYPT 197 | #include "crypt.h" 198 | #endif 199 | 200 | /* =========================================================================== 201 | Read a byte from a gz_stream; update next_in and avail_in. Return EOF 202 | for end of file. 203 | IN assertion: the stream s has been sucessfully opened for reading. 204 | */ 205 | 206 | 207 | local int unz64local_getByte OF(( 208 | const zlib_filefunc64_32_def* pzlib_filefunc_def, 209 | voidpf filestream, 210 | int *pi)); 211 | 212 | local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) 213 | { 214 | unsigned char c; 215 | int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); 216 | if (err==1) 217 | { 218 | *pi = (int)c; 219 | return UNZ_OK; 220 | } 221 | else 222 | { 223 | if (ZERROR64(*pzlib_filefunc_def,filestream)) 224 | return UNZ_ERRNO; 225 | else 226 | return UNZ_EOF; 227 | } 228 | } 229 | 230 | 231 | /* =========================================================================== 232 | Reads a long in LSB order from the given gz_stream. Sets 233 | */ 234 | local int unz64local_getShort OF(( 235 | const zlib_filefunc64_32_def* pzlib_filefunc_def, 236 | voidpf filestream, 237 | uLong *pX)); 238 | 239 | local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, 240 | voidpf filestream, 241 | uLong *pX) 242 | { 243 | uLong x ; 244 | int i = 0; 245 | int err; 246 | 247 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 248 | x = (uLong)i; 249 | 250 | if (err==UNZ_OK) 251 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 252 | x |= ((uLong)i)<<8; 253 | 254 | if (err==UNZ_OK) 255 | *pX = x; 256 | else 257 | *pX = 0; 258 | return err; 259 | } 260 | 261 | local int unz64local_getLong OF(( 262 | const zlib_filefunc64_32_def* pzlib_filefunc_def, 263 | voidpf filestream, 264 | uLong *pX)); 265 | 266 | local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, 267 | voidpf filestream, 268 | uLong *pX) 269 | { 270 | uLong x ; 271 | int i = 0; 272 | int err; 273 | 274 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 275 | x = (uLong)i; 276 | 277 | if (err==UNZ_OK) 278 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 279 | x |= ((uLong)i)<<8; 280 | 281 | if (err==UNZ_OK) 282 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 283 | x |= ((uLong)i)<<16; 284 | 285 | if (err==UNZ_OK) 286 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 287 | x += ((uLong)i)<<24; 288 | 289 | if (err==UNZ_OK) 290 | *pX = x; 291 | else 292 | *pX = 0; 293 | return err; 294 | } 295 | 296 | local int unz64local_getLong64 OF(( 297 | const zlib_filefunc64_32_def* pzlib_filefunc_def, 298 | voidpf filestream, 299 | ZPOS64_T *pX)); 300 | 301 | 302 | local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, 303 | voidpf filestream, 304 | ZPOS64_T *pX) 305 | { 306 | ZPOS64_T x ; 307 | int i = 0; 308 | int err; 309 | 310 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 311 | x = (ZPOS64_T)i; 312 | 313 | if (err==UNZ_OK) 314 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 315 | x |= ((ZPOS64_T)i)<<8; 316 | 317 | if (err==UNZ_OK) 318 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 319 | x |= ((ZPOS64_T)i)<<16; 320 | 321 | if (err==UNZ_OK) 322 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 323 | x |= ((ZPOS64_T)i)<<24; 324 | 325 | if (err==UNZ_OK) 326 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 327 | x |= ((ZPOS64_T)i)<<32; 328 | 329 | if (err==UNZ_OK) 330 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 331 | x |= ((ZPOS64_T)i)<<40; 332 | 333 | if (err==UNZ_OK) 334 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 335 | x |= ((ZPOS64_T)i)<<48; 336 | 337 | if (err==UNZ_OK) 338 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 339 | x |= ((ZPOS64_T)i)<<56; 340 | 341 | if (err==UNZ_OK) 342 | *pX = x; 343 | else 344 | *pX = 0; 345 | return err; 346 | } 347 | 348 | /* My own strcmpi / strcasecmp */ 349 | local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) 350 | { 351 | for (;;) 352 | { 353 | char c1=*(fileName1++); 354 | char c2=*(fileName2++); 355 | if ((c1>='a') && (c1<='z')) 356 | c1 -= 0x20; 357 | if ((c2>='a') && (c2<='z')) 358 | c2 -= 0x20; 359 | if (c1=='\0') 360 | return ((c2=='\0') ? 0 : -1); 361 | if (c2=='\0') 362 | return 1; 363 | if (c1c2) 366 | return 1; 367 | } 368 | } 369 | 370 | 371 | #ifdef CASESENSITIVITYDEFAULT_NO 372 | #define CASESENSITIVITYDEFAULTVALUE 2 373 | #else 374 | #define CASESENSITIVITYDEFAULTVALUE 1 375 | #endif 376 | 377 | #ifndef STRCMPCASENOSENTIVEFUNCTION 378 | #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal 379 | #endif 380 | 381 | /* 382 | Compare two filename (fileName1,fileName2). 383 | If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) 384 | If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi 385 | or strcasecmp) 386 | If iCaseSenisivity = 0, case sensitivity is defaut of your operating system 387 | (like 1 on Unix, 2 on Windows) 388 | 389 | */ 390 | extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, 391 | const char* fileName2, 392 | int iCaseSensitivity) 393 | 394 | { 395 | if (iCaseSensitivity==0) 396 | iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; 397 | 398 | if (iCaseSensitivity==1) 399 | return strcmp(fileName1,fileName2); 400 | 401 | return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); 402 | } 403 | 404 | #ifndef BUFREADCOMMENT 405 | #define BUFREADCOMMENT (0x400) 406 | #endif 407 | 408 | /* 409 | Locate the Central directory of a zipfile (at the end, just before 410 | the global comment) 411 | */ 412 | local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); 413 | local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) 414 | { 415 | unsigned char* buf; 416 | ZPOS64_T uSizeFile; 417 | ZPOS64_T uBackRead; 418 | ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ 419 | ZPOS64_T uPosFound=0; 420 | 421 | if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 422 | return 0; 423 | 424 | 425 | uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); 426 | 427 | if (uMaxBack>uSizeFile) 428 | uMaxBack = uSizeFile; 429 | 430 | buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); 431 | if (buf==NULL) 432 | return 0; 433 | 434 | uBackRead = 4; 435 | while (uBackReaduMaxBack) 441 | uBackRead = uMaxBack; 442 | else 443 | uBackRead+=BUFREADCOMMENT; 444 | uReadPos = uSizeFile-uBackRead ; 445 | 446 | uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 447 | (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); 448 | if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) 449 | break; 450 | 451 | if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) 452 | break; 453 | 454 | for (i=(int)uReadSize-3; (i--)>0;) 455 | if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 456 | ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) 457 | { 458 | uPosFound = uReadPos+i; 459 | break; 460 | } 461 | 462 | if (uPosFound!=0) 463 | break; 464 | } 465 | TRYFREE(buf); 466 | return uPosFound; 467 | } 468 | 469 | 470 | /* 471 | Locate the Central directory 64 of a zipfile (at the end, just before 472 | the global comment) 473 | */ 474 | local ZPOS64_T unz64local_SearchCentralDir64 OF(( 475 | const zlib_filefunc64_32_def* pzlib_filefunc_def, 476 | voidpf filestream)); 477 | 478 | local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, 479 | voidpf filestream) 480 | { 481 | unsigned char* buf; 482 | ZPOS64_T uSizeFile; 483 | ZPOS64_T uBackRead; 484 | ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ 485 | ZPOS64_T uPosFound=0; 486 | uLong uL; 487 | ZPOS64_T relativeOffset; 488 | 489 | if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 490 | return 0; 491 | 492 | 493 | uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); 494 | 495 | if (uMaxBack>uSizeFile) 496 | uMaxBack = uSizeFile; 497 | 498 | buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); 499 | if (buf==NULL) 500 | return 0; 501 | 502 | uBackRead = 4; 503 | while (uBackReaduMaxBack) 509 | uBackRead = uMaxBack; 510 | else 511 | uBackRead+=BUFREADCOMMENT; 512 | uReadPos = uSizeFile-uBackRead ; 513 | 514 | uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 515 | (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); 516 | if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) 517 | break; 518 | 519 | if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) 520 | break; 521 | 522 | for (i=(int)uReadSize-3; (i--)>0;) 523 | if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 524 | ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) 525 | { 526 | uPosFound = uReadPos+i; 527 | break; 528 | } 529 | 530 | if (uPosFound!=0) 531 | break; 532 | } 533 | TRYFREE(buf); 534 | if (uPosFound == 0) 535 | return 0; 536 | 537 | /* Zip64 end of central directory locator */ 538 | if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) 539 | return 0; 540 | 541 | /* the signature, already checked */ 542 | if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) 543 | return 0; 544 | 545 | /* number of the disk with the start of the zip64 end of central directory */ 546 | if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) 547 | return 0; 548 | if (uL != 0) 549 | return 0; 550 | 551 | /* relative offset of the zip64 end of central directory record */ 552 | if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) 553 | return 0; 554 | 555 | /* total number of disks */ 556 | if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) 557 | return 0; 558 | if (uL != 1) 559 | return 0; 560 | 561 | /* Goto end of central directory record */ 562 | if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) 563 | return 0; 564 | 565 | /* the signature */ 566 | if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) 567 | return 0; 568 | 569 | if (uL != 0x06064b50) 570 | return 0; 571 | 572 | return relativeOffset; 573 | } 574 | 575 | /* 576 | Open a Zip file. path contain the full pathname (by example, 577 | on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer 578 | "zlib/zlib114.zip". 579 | If the zipfile cannot be opened (file doesn't exist or in not valid), the 580 | return value is NULL. 581 | Else, the return value is a unzFile Handle, usable with other function 582 | of this unzip package. 583 | */ 584 | local unzFile unzOpenInternal (const void *path, 585 | zlib_filefunc64_32_def* pzlib_filefunc64_32_def, 586 | int is64bitOpenFunction) 587 | { 588 | unz64_s us; 589 | unz64_s *s; 590 | ZPOS64_T central_pos; 591 | uLong uL; 592 | 593 | uLong number_disk; /* number of the current dist, used for 594 | spaning ZIP, unsupported, always 0*/ 595 | uLong number_disk_with_CD; /* number the the disk with central dir, used 596 | for spaning ZIP, unsupported, always 0*/ 597 | ZPOS64_T number_entry_CD; /* total number of entries in 598 | the central dir 599 | (same than number_entry on nospan) */ 600 | 601 | int err=UNZ_OK; 602 | 603 | if (unz_copyright[0]!=' ') 604 | return NULL; 605 | 606 | us.z_filefunc.zseek32_file = NULL; 607 | us.z_filefunc.ztell32_file = NULL; 608 | if (pzlib_filefunc64_32_def==NULL) 609 | fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); 610 | else 611 | us.z_filefunc = *pzlib_filefunc64_32_def; 612 | us.is64bitOpenFunction = is64bitOpenFunction; 613 | 614 | 615 | 616 | us.filestream = ZOPEN64(us.z_filefunc, 617 | path, 618 | ZLIB_FILEFUNC_MODE_READ | 619 | ZLIB_FILEFUNC_MODE_EXISTING); 620 | if (us.filestream==NULL) 621 | return NULL; 622 | 623 | central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); 624 | if (central_pos) 625 | { 626 | uLong uS; 627 | ZPOS64_T uL64; 628 | 629 | us.isZip64 = 1; 630 | 631 | if (ZSEEK64(us.z_filefunc, us.filestream, 632 | central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) 633 | err=UNZ_ERRNO; 634 | 635 | /* the signature, already checked */ 636 | if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 637 | err=UNZ_ERRNO; 638 | 639 | /* size of zip64 end of central directory record */ 640 | if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) 641 | err=UNZ_ERRNO; 642 | 643 | /* version made by */ 644 | if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) 645 | err=UNZ_ERRNO; 646 | 647 | /* version needed to extract */ 648 | if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) 649 | err=UNZ_ERRNO; 650 | 651 | /* number of this disk */ 652 | if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) 653 | err=UNZ_ERRNO; 654 | 655 | /* number of the disk with the start of the central directory */ 656 | if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) 657 | err=UNZ_ERRNO; 658 | 659 | /* total number of entries in the central directory on this disk */ 660 | if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) 661 | err=UNZ_ERRNO; 662 | 663 | /* total number of entries in the central directory */ 664 | if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) 665 | err=UNZ_ERRNO; 666 | 667 | if ((number_entry_CD!=us.gi.number_entry) || 668 | (number_disk_with_CD!=0) || 669 | (number_disk!=0)) 670 | err=UNZ_BADZIPFILE; 671 | 672 | /* size of the central directory */ 673 | if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) 674 | err=UNZ_ERRNO; 675 | 676 | /* offset of start of central directory with respect to the 677 | starting disk number */ 678 | if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) 679 | err=UNZ_ERRNO; 680 | 681 | us.gi.size_comment = 0; 682 | } 683 | else 684 | { 685 | central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); 686 | if (central_pos==0) 687 | err=UNZ_ERRNO; 688 | 689 | us.isZip64 = 0; 690 | 691 | if (ZSEEK64(us.z_filefunc, us.filestream, 692 | central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) 693 | err=UNZ_ERRNO; 694 | 695 | /* the signature, already checked */ 696 | if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 697 | err=UNZ_ERRNO; 698 | 699 | /* number of this disk */ 700 | if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) 701 | err=UNZ_ERRNO; 702 | 703 | /* number of the disk with the start of the central directory */ 704 | if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) 705 | err=UNZ_ERRNO; 706 | 707 | /* total number of entries in the central dir on this disk */ 708 | if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 709 | err=UNZ_ERRNO; 710 | us.gi.number_entry = uL; 711 | 712 | /* total number of entries in the central dir */ 713 | if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 714 | err=UNZ_ERRNO; 715 | number_entry_CD = uL; 716 | 717 | if ((number_entry_CD!=us.gi.number_entry) || 718 | (number_disk_with_CD!=0) || 719 | (number_disk!=0)) 720 | err=UNZ_BADZIPFILE; 721 | 722 | /* size of the central directory */ 723 | if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 724 | err=UNZ_ERRNO; 725 | us.size_central_dir = uL; 726 | 727 | /* offset of start of central directory with respect to the 728 | starting disk number */ 729 | if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 730 | err=UNZ_ERRNO; 731 | us.offset_central_dir = uL; 732 | 733 | /* zipfile comment length */ 734 | if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) 735 | err=UNZ_ERRNO; 736 | } 737 | 738 | if ((central_pospfile_in_zip_read!=NULL) 816 | unzCloseCurrentFile(file); 817 | 818 | ZCLOSE64(s->z_filefunc, s->filestream); 819 | TRYFREE(s); 820 | return UNZ_OK; 821 | } 822 | 823 | 824 | /* 825 | Write info about the ZipFile in the *pglobal_info structure. 826 | No preparation of the structure is needed 827 | return UNZ_OK if there is no problem. */ 828 | extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) 829 | { 830 | unz64_s* s; 831 | if (file==NULL) 832 | return UNZ_PARAMERROR; 833 | s=(unz64_s*)file; 834 | *pglobal_info=s->gi; 835 | return UNZ_OK; 836 | } 837 | 838 | extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) 839 | { 840 | unz64_s* s; 841 | if (file==NULL) 842 | return UNZ_PARAMERROR; 843 | s=(unz64_s*)file; 844 | /* to do : check if number_entry is not truncated */ 845 | pglobal_info32->number_entry = (uLong)s->gi.number_entry; 846 | pglobal_info32->size_comment = s->gi.size_comment; 847 | return UNZ_OK; 848 | } 849 | /* 850 | Translate date/time from Dos format to tm_unz (readable more easilty) 851 | */ 852 | local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) 853 | { 854 | ZPOS64_T uDate; 855 | uDate = (ZPOS64_T)(ulDosDate>>16); 856 | ptm->tm_mday = (uInt)(uDate&0x1f) ; 857 | ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; 858 | ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; 859 | 860 | ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); 861 | ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; 862 | ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; 863 | } 864 | 865 | /* 866 | Get Info about the current file in the zipfile, with internal only info 867 | */ 868 | local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, 869 | unz_file_info64 *pfile_info, 870 | unz_file_info64_internal 871 | *pfile_info_internal, 872 | char *szFileName, 873 | uLong fileNameBufferSize, 874 | void *extraField, 875 | uLong extraFieldBufferSize, 876 | char *szComment, 877 | uLong commentBufferSize)); 878 | 879 | local int unz64local_GetCurrentFileInfoInternal (unzFile file, 880 | unz_file_info64 *pfile_info, 881 | unz_file_info64_internal 882 | *pfile_info_internal, 883 | char *szFileName, 884 | uLong fileNameBufferSize, 885 | void *extraField, 886 | uLong extraFieldBufferSize, 887 | char *szComment, 888 | uLong commentBufferSize) 889 | { 890 | unz64_s* s; 891 | unz_file_info64 file_info; 892 | unz_file_info64_internal file_info_internal; 893 | int err=UNZ_OK; 894 | uLong uMagic; 895 | long lSeek=0; 896 | uLong uL; 897 | 898 | if (file==NULL) 899 | return UNZ_PARAMERROR; 900 | s=(unz64_s*)file; 901 | if (ZSEEK64(s->z_filefunc, s->filestream, 902 | s->pos_in_central_dir+s->byte_before_the_zipfile, 903 | ZLIB_FILEFUNC_SEEK_SET)!=0) 904 | err=UNZ_ERRNO; 905 | 906 | 907 | /* we check the magic */ 908 | if (err==UNZ_OK) 909 | { 910 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) 911 | err=UNZ_ERRNO; 912 | else if (uMagic!=0x02014b50) 913 | err=UNZ_BADZIPFILE; 914 | } 915 | 916 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) 917 | err=UNZ_ERRNO; 918 | 919 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) 920 | err=UNZ_ERRNO; 921 | 922 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) 923 | err=UNZ_ERRNO; 924 | 925 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) 926 | err=UNZ_ERRNO; 927 | 928 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) 929 | err=UNZ_ERRNO; 930 | 931 | unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); 932 | 933 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) 934 | err=UNZ_ERRNO; 935 | 936 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) 937 | err=UNZ_ERRNO; 938 | file_info.compressed_size = uL; 939 | 940 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) 941 | err=UNZ_ERRNO; 942 | file_info.uncompressed_size = uL; 943 | 944 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) 945 | err=UNZ_ERRNO; 946 | 947 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) 948 | err=UNZ_ERRNO; 949 | 950 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) 951 | err=UNZ_ERRNO; 952 | 953 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) 954 | err=UNZ_ERRNO; 955 | 956 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) 957 | err=UNZ_ERRNO; 958 | 959 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) 960 | err=UNZ_ERRNO; 961 | 962 | // relative offset of local header 963 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) 964 | err=UNZ_ERRNO; 965 | file_info_internal.offset_curfile = uL; 966 | 967 | lSeek+=file_info.size_filename; 968 | if ((err==UNZ_OK) && (szFileName!=NULL)) 969 | { 970 | uLong uSizeRead ; 971 | if (file_info.size_filename0) && (fileNameBufferSize>0)) 980 | if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) 981 | err=UNZ_ERRNO; 982 | lSeek -= uSizeRead; 983 | } 984 | 985 | // Read extrafield 986 | if ((err==UNZ_OK) && (extraField!=NULL)) 987 | { 988 | ZPOS64_T uSizeRead ; 989 | if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) 997 | lSeek=0; 998 | else 999 | err=UNZ_ERRNO; 1000 | } 1001 | 1002 | if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) 1003 | if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) 1004 | err=UNZ_ERRNO; 1005 | 1006 | lSeek += file_info.size_file_extra - (uLong)uSizeRead; 1007 | } 1008 | else 1009 | lSeek += file_info.size_file_extra; 1010 | 1011 | 1012 | if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) 1013 | { 1014 | uLong acc = 0; 1015 | 1016 | // since lSeek now points to after the extra field we need to move back 1017 | lSeek -= file_info.size_file_extra; 1018 | 1019 | if (lSeek!=0) 1020 | { 1021 | if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) 1022 | lSeek=0; 1023 | else 1024 | err=UNZ_ERRNO; 1025 | } 1026 | 1027 | while(acc < file_info.size_file_extra) 1028 | { 1029 | uLong headerId; 1030 | uLong dataSize; 1031 | 1032 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) 1033 | err=UNZ_ERRNO; 1034 | 1035 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) 1036 | err=UNZ_ERRNO; 1037 | 1038 | /* ZIP64 extra fields */ 1039 | if (headerId == 0x0001) 1040 | { 1041 | uLong uL; 1042 | 1043 | if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1) 1044 | { 1045 | if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) 1046 | err=UNZ_ERRNO; 1047 | } 1048 | 1049 | if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1) 1050 | { 1051 | if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) 1052 | err=UNZ_ERRNO; 1053 | } 1054 | 1055 | if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1) 1056 | { 1057 | /* Relative Header offset */ 1058 | if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) 1059 | err=UNZ_ERRNO; 1060 | } 1061 | 1062 | if(file_info.disk_num_start == (unsigned long)-1) 1063 | { 1064 | /* Disk Start Number */ 1065 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) 1066 | err=UNZ_ERRNO; 1067 | } 1068 | 1069 | } 1070 | else 1071 | { 1072 | if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) 1073 | err=UNZ_ERRNO; 1074 | } 1075 | 1076 | acc += 2 + 2 + dataSize; 1077 | } 1078 | } 1079 | 1080 | if ((err==UNZ_OK) && (szComment!=NULL)) 1081 | { 1082 | uLong uSizeRead ; 1083 | if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) 1094 | lSeek=0; 1095 | else 1096 | err=UNZ_ERRNO; 1097 | } 1098 | 1099 | if ((file_info.size_file_comment>0) && (commentBufferSize>0)) 1100 | if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) 1101 | err=UNZ_ERRNO; 1102 | lSeek+=file_info.size_file_comment - uSizeRead; 1103 | } 1104 | else 1105 | lSeek+=file_info.size_file_comment; 1106 | 1107 | 1108 | if ((err==UNZ_OK) && (pfile_info!=NULL)) 1109 | *pfile_info=file_info; 1110 | 1111 | if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) 1112 | *pfile_info_internal=file_info_internal; 1113 | 1114 | return err; 1115 | } 1116 | 1117 | 1118 | 1119 | /* 1120 | Write info about the ZipFile in the *pglobal_info structure. 1121 | No preparation of the structure is needed 1122 | return UNZ_OK if there is no problem. 1123 | */ 1124 | extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, 1125 | unz_file_info64 * pfile_info, 1126 | char * szFileName, uLong fileNameBufferSize, 1127 | void *extraField, uLong extraFieldBufferSize, 1128 | char* szComment, uLong commentBufferSize) 1129 | { 1130 | return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, 1131 | szFileName,fileNameBufferSize, 1132 | extraField,extraFieldBufferSize, 1133 | szComment,commentBufferSize); 1134 | } 1135 | 1136 | extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, 1137 | unz_file_info * pfile_info, 1138 | char * szFileName, uLong fileNameBufferSize, 1139 | void *extraField, uLong extraFieldBufferSize, 1140 | char* szComment, uLong commentBufferSize) 1141 | { 1142 | int err; 1143 | unz_file_info64 file_info64; 1144 | err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, 1145 | szFileName,fileNameBufferSize, 1146 | extraField,extraFieldBufferSize, 1147 | szComment,commentBufferSize); 1148 | if (err==UNZ_OK) 1149 | { 1150 | pfile_info->version = file_info64.version; 1151 | pfile_info->version_needed = file_info64.version_needed; 1152 | pfile_info->flag = file_info64.flag; 1153 | pfile_info->compression_method = file_info64.compression_method; 1154 | pfile_info->dosDate = file_info64.dosDate; 1155 | pfile_info->crc = file_info64.crc; 1156 | 1157 | pfile_info->size_filename = file_info64.size_filename; 1158 | pfile_info->size_file_extra = file_info64.size_file_extra; 1159 | pfile_info->size_file_comment = file_info64.size_file_comment; 1160 | 1161 | pfile_info->disk_num_start = file_info64.disk_num_start; 1162 | pfile_info->internal_fa = file_info64.internal_fa; 1163 | pfile_info->external_fa = file_info64.external_fa; 1164 | 1165 | pfile_info->tmu_date = file_info64.tmu_date, 1166 | 1167 | 1168 | pfile_info->compressed_size = (uLong)file_info64.compressed_size; 1169 | pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; 1170 | 1171 | } 1172 | return err; 1173 | } 1174 | /* 1175 | Set the current file of the zipfile to the first file. 1176 | return UNZ_OK if there is no problem 1177 | */ 1178 | extern int ZEXPORT unzGoToFirstFile (unzFile file) 1179 | { 1180 | int err=UNZ_OK; 1181 | unz64_s* s; 1182 | if (file==NULL) 1183 | return UNZ_PARAMERROR; 1184 | s=(unz64_s*)file; 1185 | s->pos_in_central_dir=s->offset_central_dir; 1186 | s->num_file=0; 1187 | err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, 1188 | &s->cur_file_info_internal, 1189 | NULL,0,NULL,0,NULL,0); 1190 | s->current_file_ok = (err == UNZ_OK); 1191 | return err; 1192 | } 1193 | 1194 | /* 1195 | Set the current file of the zipfile to the next file. 1196 | return UNZ_OK if there is no problem 1197 | return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. 1198 | */ 1199 | extern int ZEXPORT unzGoToNextFile (unzFile file) 1200 | { 1201 | unz64_s* s; 1202 | int err; 1203 | 1204 | if (file==NULL) 1205 | return UNZ_PARAMERROR; 1206 | s=(unz64_s*)file; 1207 | if (!s->current_file_ok) 1208 | return UNZ_END_OF_LIST_OF_FILE; 1209 | if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ 1210 | if (s->num_file+1==s->gi.number_entry) 1211 | return UNZ_END_OF_LIST_OF_FILE; 1212 | 1213 | s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + 1214 | s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; 1215 | s->num_file++; 1216 | err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, 1217 | &s->cur_file_info_internal, 1218 | NULL,0,NULL,0,NULL,0); 1219 | s->current_file_ok = (err == UNZ_OK); 1220 | return err; 1221 | } 1222 | 1223 | 1224 | /* 1225 | Try locate the file szFileName in the zipfile. 1226 | For the iCaseSensitivity signification, see unzipStringFileNameCompare 1227 | 1228 | return value : 1229 | UNZ_OK if the file is found. It becomes the current file. 1230 | UNZ_END_OF_LIST_OF_FILE if the file is not found 1231 | */ 1232 | extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) 1233 | { 1234 | unz64_s* s; 1235 | int err; 1236 | 1237 | /* We remember the 'current' position in the file so that we can jump 1238 | * back there if we fail. 1239 | */ 1240 | unz_file_info64 cur_file_infoSaved; 1241 | unz_file_info64_internal cur_file_info_internalSaved; 1242 | ZPOS64_T num_fileSaved; 1243 | ZPOS64_T pos_in_central_dirSaved; 1244 | 1245 | 1246 | if (file==NULL) 1247 | return UNZ_PARAMERROR; 1248 | 1249 | if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) 1250 | return UNZ_PARAMERROR; 1251 | 1252 | s=(unz64_s*)file; 1253 | if (!s->current_file_ok) 1254 | return UNZ_END_OF_LIST_OF_FILE; 1255 | 1256 | /* Save the current state */ 1257 | num_fileSaved = s->num_file; 1258 | pos_in_central_dirSaved = s->pos_in_central_dir; 1259 | cur_file_infoSaved = s->cur_file_info; 1260 | cur_file_info_internalSaved = s->cur_file_info_internal; 1261 | 1262 | err = unzGoToFirstFile(file); 1263 | 1264 | while (err == UNZ_OK) 1265 | { 1266 | char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; 1267 | err = unzGetCurrentFileInfo64(file,NULL, 1268 | szCurrentFileName,sizeof(szCurrentFileName)-1, 1269 | NULL,0,NULL,0); 1270 | if (err == UNZ_OK) 1271 | { 1272 | if (unzStringFileNameCompare(szCurrentFileName, 1273 | szFileName,iCaseSensitivity)==0) 1274 | return UNZ_OK; 1275 | err = unzGoToNextFile(file); 1276 | } 1277 | } 1278 | 1279 | /* We failed, so restore the state of the 'current file' to where we 1280 | * were. 1281 | */ 1282 | s->num_file = num_fileSaved ; 1283 | s->pos_in_central_dir = pos_in_central_dirSaved ; 1284 | s->cur_file_info = cur_file_infoSaved; 1285 | s->cur_file_info_internal = cur_file_info_internalSaved; 1286 | return err; 1287 | } 1288 | 1289 | 1290 | /* 1291 | /////////////////////////////////////////// 1292 | // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) 1293 | // I need random access 1294 | // 1295 | // Further optimization could be realized by adding an ability 1296 | // to cache the directory in memory. The goal being a single 1297 | // comprehensive file read to put the file I need in a memory. 1298 | */ 1299 | 1300 | /* 1301 | typedef struct unz_file_pos_s 1302 | { 1303 | ZPOS64_T pos_in_zip_directory; // offset in file 1304 | ZPOS64_T num_of_file; // # of file 1305 | } unz_file_pos; 1306 | */ 1307 | 1308 | extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) 1309 | { 1310 | unz64_s* s; 1311 | 1312 | if (file==NULL || file_pos==NULL) 1313 | return UNZ_PARAMERROR; 1314 | s=(unz64_s*)file; 1315 | if (!s->current_file_ok) 1316 | return UNZ_END_OF_LIST_OF_FILE; 1317 | 1318 | file_pos->pos_in_zip_directory = s->pos_in_central_dir; 1319 | file_pos->num_of_file = s->num_file; 1320 | 1321 | return UNZ_OK; 1322 | } 1323 | 1324 | extern int ZEXPORT unzGetFilePos( 1325 | unzFile file, 1326 | unz_file_pos* file_pos) 1327 | { 1328 | unz64_file_pos file_pos64; 1329 | int err = unzGetFilePos64(file,&file_pos64); 1330 | if (err==UNZ_OK) 1331 | { 1332 | file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; 1333 | file_pos->num_of_file = (uLong)file_pos64.num_of_file; 1334 | } 1335 | return err; 1336 | } 1337 | 1338 | extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) 1339 | { 1340 | unz64_s* s; 1341 | int err; 1342 | 1343 | if (file==NULL || file_pos==NULL) 1344 | return UNZ_PARAMERROR; 1345 | s=(unz64_s*)file; 1346 | 1347 | /* jump to the right spot */ 1348 | s->pos_in_central_dir = file_pos->pos_in_zip_directory; 1349 | s->num_file = file_pos->num_of_file; 1350 | 1351 | /* set the current file */ 1352 | err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, 1353 | &s->cur_file_info_internal, 1354 | NULL,0,NULL,0,NULL,0); 1355 | /* return results */ 1356 | s->current_file_ok = (err == UNZ_OK); 1357 | return err; 1358 | } 1359 | 1360 | extern int ZEXPORT unzGoToFilePos( 1361 | unzFile file, 1362 | unz_file_pos* file_pos) 1363 | { 1364 | unz64_file_pos file_pos64; 1365 | if (file_pos == NULL) 1366 | return UNZ_PARAMERROR; 1367 | 1368 | file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; 1369 | file_pos64.num_of_file = file_pos->num_of_file; 1370 | return unzGoToFilePos64(file,&file_pos64); 1371 | } 1372 | 1373 | /* 1374 | // Unzip Helper Functions - should be here? 1375 | /////////////////////////////////////////// 1376 | */ 1377 | 1378 | /* 1379 | Read the local header of the current zipfile 1380 | Check the coherency of the local header and info in the end of central 1381 | directory about this file 1382 | store in *piSizeVar the size of extra info in local header 1383 | (filename and size of extra field data) 1384 | */ 1385 | local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, 1386 | ZPOS64_T * poffset_local_extrafield, 1387 | uInt * psize_local_extrafield) 1388 | { 1389 | uLong uMagic,uData,uFlags; 1390 | uLong size_filename; 1391 | uLong size_extra_field; 1392 | int err=UNZ_OK; 1393 | 1394 | *piSizeVar = 0; 1395 | *poffset_local_extrafield = 0; 1396 | *psize_local_extrafield = 0; 1397 | 1398 | if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + 1399 | s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) 1400 | return UNZ_ERRNO; 1401 | 1402 | 1403 | if (err==UNZ_OK) 1404 | { 1405 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) 1406 | err=UNZ_ERRNO; 1407 | else if (uMagic!=0x04034b50) 1408 | err=UNZ_BADZIPFILE; 1409 | } 1410 | 1411 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) 1412 | err=UNZ_ERRNO; 1413 | /* 1414 | else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) 1415 | err=UNZ_BADZIPFILE; 1416 | */ 1417 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) 1418 | err=UNZ_ERRNO; 1419 | 1420 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) 1421 | err=UNZ_ERRNO; 1422 | else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) 1423 | err=UNZ_BADZIPFILE; 1424 | 1425 | if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && 1426 | /* #ifdef HAVE_BZIP2 */ 1427 | (s->cur_file_info.compression_method!=Z_BZIP2ED) && 1428 | /* #endif */ 1429 | (s->cur_file_info.compression_method!=Z_DEFLATED)) 1430 | err=UNZ_BADZIPFILE; 1431 | 1432 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ 1433 | err=UNZ_ERRNO; 1434 | 1435 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ 1436 | err=UNZ_ERRNO; 1437 | else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) 1438 | err=UNZ_BADZIPFILE; 1439 | 1440 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ 1441 | err=UNZ_ERRNO; 1442 | else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) 1443 | err=UNZ_BADZIPFILE; 1444 | 1445 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ 1446 | err=UNZ_ERRNO; 1447 | else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) 1448 | err=UNZ_BADZIPFILE; 1449 | 1450 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) 1451 | err=UNZ_ERRNO; 1452 | else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) 1453 | err=UNZ_BADZIPFILE; 1454 | 1455 | *piSizeVar += (uInt)size_filename; 1456 | 1457 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) 1458 | err=UNZ_ERRNO; 1459 | *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + 1460 | SIZEZIPLOCALHEADER + size_filename; 1461 | *psize_local_extrafield = (uInt)size_extra_field; 1462 | 1463 | *piSizeVar += (uInt)size_extra_field; 1464 | 1465 | return err; 1466 | } 1467 | 1468 | /* 1469 | Open for reading data the current file in the zipfile. 1470 | If there is no error and the file is opened, the return value is UNZ_OK. 1471 | */ 1472 | extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, 1473 | int* level, int raw, const char* password) 1474 | { 1475 | int err=UNZ_OK; 1476 | uInt iSizeVar; 1477 | unz64_s* s; 1478 | file_in_zip64_read_info_s* pfile_in_zip_read_info; 1479 | ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ 1480 | uInt size_local_extrafield; /* size of the local extra field */ 1481 | # ifndef NOUNCRYPT 1482 | char source[12]; 1483 | # else 1484 | if (password != NULL) 1485 | return UNZ_PARAMERROR; 1486 | # endif 1487 | 1488 | if (file==NULL) 1489 | return UNZ_PARAMERROR; 1490 | s=(unz64_s*)file; 1491 | if (!s->current_file_ok) 1492 | return UNZ_PARAMERROR; 1493 | 1494 | if (s->pfile_in_zip_read != NULL) 1495 | unzCloseCurrentFile(file); 1496 | 1497 | if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) 1498 | return UNZ_BADZIPFILE; 1499 | 1500 | pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); 1501 | if (pfile_in_zip_read_info==NULL) 1502 | return UNZ_INTERNALERROR; 1503 | 1504 | pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); 1505 | pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; 1506 | pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; 1507 | pfile_in_zip_read_info->pos_local_extrafield=0; 1508 | pfile_in_zip_read_info->raw=raw; 1509 | 1510 | if (pfile_in_zip_read_info->read_buffer==NULL) 1511 | { 1512 | TRYFREE(pfile_in_zip_read_info); 1513 | return UNZ_INTERNALERROR; 1514 | } 1515 | 1516 | pfile_in_zip_read_info->stream_initialised=0; 1517 | 1518 | if (method!=NULL) 1519 | *method = (int)s->cur_file_info.compression_method; 1520 | 1521 | if (level!=NULL) 1522 | { 1523 | *level = 6; 1524 | switch (s->cur_file_info.flag & 0x06) 1525 | { 1526 | case 6 : *level = 1; break; 1527 | case 4 : *level = 2; break; 1528 | case 2 : *level = 9; break; 1529 | } 1530 | } 1531 | 1532 | if ((s->cur_file_info.compression_method!=0) && 1533 | /* #ifdef HAVE_BZIP2 */ 1534 | (s->cur_file_info.compression_method!=Z_BZIP2ED) && 1535 | /* #endif */ 1536 | (s->cur_file_info.compression_method!=Z_DEFLATED)) 1537 | 1538 | err=UNZ_BADZIPFILE; 1539 | 1540 | pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; 1541 | pfile_in_zip_read_info->crc32=0; 1542 | pfile_in_zip_read_info->total_out_64=0; 1543 | pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; 1544 | pfile_in_zip_read_info->filestream=s->filestream; 1545 | pfile_in_zip_read_info->z_filefunc=s->z_filefunc; 1546 | pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; 1547 | 1548 | pfile_in_zip_read_info->stream.total_out = 0; 1549 | 1550 | if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) 1551 | { 1552 | #ifdef HAVE_BZIP2 1553 | pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; 1554 | pfile_in_zip_read_info->bstream.bzfree = (free_func)0; 1555 | pfile_in_zip_read_info->bstream.opaque = (voidpf)0; 1556 | pfile_in_zip_read_info->bstream.state = (voidpf)0; 1557 | 1558 | pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; 1559 | pfile_in_zip_read_info->stream.zfree = (free_func)0; 1560 | pfile_in_zip_read_info->stream.opaque = (voidpf)0; 1561 | pfile_in_zip_read_info->stream.next_in = (voidpf)0; 1562 | pfile_in_zip_read_info->stream.avail_in = 0; 1563 | 1564 | err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); 1565 | if (err == Z_OK) 1566 | pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; 1567 | else 1568 | { 1569 | TRYFREE(pfile_in_zip_read_info); 1570 | return err; 1571 | } 1572 | #else 1573 | pfile_in_zip_read_info->raw=1; 1574 | #endif 1575 | } 1576 | else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) 1577 | { 1578 | pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; 1579 | pfile_in_zip_read_info->stream.zfree = (free_func)0; 1580 | pfile_in_zip_read_info->stream.opaque = (voidpf)0; 1581 | pfile_in_zip_read_info->stream.next_in = 0; 1582 | pfile_in_zip_read_info->stream.avail_in = 0; 1583 | 1584 | err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); 1585 | if (err == Z_OK) 1586 | pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; 1587 | else 1588 | { 1589 | TRYFREE(pfile_in_zip_read_info); 1590 | return err; 1591 | } 1592 | /* windowBits is passed < 0 to tell that there is no zlib header. 1593 | * Note that in this case inflate *requires* an extra "dummy" byte 1594 | * after the compressed stream in order to complete decompression and 1595 | * return Z_STREAM_END. 1596 | * In unzip, i don't wait absolutely Z_STREAM_END because I known the 1597 | * size of both compressed and uncompressed data 1598 | */ 1599 | } 1600 | pfile_in_zip_read_info->rest_read_compressed = 1601 | s->cur_file_info.compressed_size ; 1602 | pfile_in_zip_read_info->rest_read_uncompressed = 1603 | s->cur_file_info.uncompressed_size ; 1604 | 1605 | 1606 | pfile_in_zip_read_info->pos_in_zipfile = 1607 | s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + 1608 | iSizeVar; 1609 | 1610 | pfile_in_zip_read_info->stream.avail_in = (uInt)0; 1611 | 1612 | s->pfile_in_zip_read = pfile_in_zip_read_info; 1613 | s->encrypted = 0; 1614 | 1615 | # ifndef NOUNCRYPT 1616 | if (password != NULL) 1617 | { 1618 | int i; 1619 | s->pcrc_32_tab = get_crc_table(); 1620 | init_keys(password,s->keys,s->pcrc_32_tab); 1621 | if (ZSEEK64(s->z_filefunc, s->filestream, 1622 | s->pfile_in_zip_read->pos_in_zipfile + 1623 | s->pfile_in_zip_read->byte_before_the_zipfile, 1624 | SEEK_SET)!=0) 1625 | return UNZ_INTERNALERROR; 1626 | if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) 1627 | return UNZ_INTERNALERROR; 1628 | 1629 | for (i = 0; i<12; i++) 1630 | zdecode(s->keys,s->pcrc_32_tab,source[i]); 1631 | 1632 | s->pfile_in_zip_read->pos_in_zipfile+=12; 1633 | s->encrypted=1; 1634 | } 1635 | # endif 1636 | 1637 | 1638 | return UNZ_OK; 1639 | } 1640 | 1641 | extern int ZEXPORT unzOpenCurrentFile (unzFile file) 1642 | { 1643 | return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); 1644 | } 1645 | 1646 | extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) 1647 | { 1648 | return unzOpenCurrentFile3(file, NULL, NULL, 0, password); 1649 | } 1650 | 1651 | extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) 1652 | { 1653 | return unzOpenCurrentFile3(file, method, level, raw, NULL); 1654 | } 1655 | 1656 | /** Addition for GDAL : START */ 1657 | 1658 | extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) 1659 | { 1660 | unz64_s* s; 1661 | file_in_zip64_read_info_s* pfile_in_zip_read_info; 1662 | s=(unz64_s*)file; 1663 | if (file==NULL) 1664 | return 0; //UNZ_PARAMERROR; 1665 | pfile_in_zip_read_info=s->pfile_in_zip_read; 1666 | if (pfile_in_zip_read_info==NULL) 1667 | return 0; //UNZ_PARAMERROR; 1668 | return pfile_in_zip_read_info->pos_in_zipfile + 1669 | pfile_in_zip_read_info->byte_before_the_zipfile; 1670 | } 1671 | 1672 | /** Addition for GDAL : END */ 1673 | 1674 | /* 1675 | Read bytes from the current file. 1676 | buf contain buffer where data must be copied 1677 | len the size of buf. 1678 | 1679 | return the number of byte copied if somes bytes are copied 1680 | return 0 if the end of file was reached 1681 | return <0 with error code if there is an error 1682 | (UNZ_ERRNO for IO error, or zLib error for uncompress error) 1683 | */ 1684 | extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) 1685 | { 1686 | int err=UNZ_OK; 1687 | uInt iRead = 0; 1688 | unz64_s* s; 1689 | file_in_zip64_read_info_s* pfile_in_zip_read_info; 1690 | if (file==NULL) 1691 | return UNZ_PARAMERROR; 1692 | s=(unz64_s*)file; 1693 | pfile_in_zip_read_info=s->pfile_in_zip_read; 1694 | 1695 | if (pfile_in_zip_read_info==NULL) 1696 | return UNZ_PARAMERROR; 1697 | 1698 | 1699 | if ((pfile_in_zip_read_info->read_buffer == NULL)) 1700 | return UNZ_END_OF_LIST_OF_FILE; 1701 | if (len==0) 1702 | return 0; 1703 | 1704 | pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; 1705 | 1706 | pfile_in_zip_read_info->stream.avail_out = (uInt)len; 1707 | 1708 | if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && 1709 | (!(pfile_in_zip_read_info->raw))) 1710 | pfile_in_zip_read_info->stream.avail_out = 1711 | (uInt)pfile_in_zip_read_info->rest_read_uncompressed; 1712 | 1713 | if ((len>pfile_in_zip_read_info->rest_read_compressed+ 1714 | pfile_in_zip_read_info->stream.avail_in) && 1715 | (pfile_in_zip_read_info->raw)) 1716 | pfile_in_zip_read_info->stream.avail_out = 1717 | (uInt)pfile_in_zip_read_info->rest_read_compressed+ 1718 | pfile_in_zip_read_info->stream.avail_in; 1719 | 1720 | while (pfile_in_zip_read_info->stream.avail_out>0) 1721 | { 1722 | if ((pfile_in_zip_read_info->stream.avail_in==0) && 1723 | (pfile_in_zip_read_info->rest_read_compressed>0)) 1724 | { 1725 | uInt uReadThis = UNZ_BUFSIZE; 1726 | if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; 1728 | if (uReadThis == 0) 1729 | return UNZ_EOF; 1730 | if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, 1731 | pfile_in_zip_read_info->filestream, 1732 | pfile_in_zip_read_info->pos_in_zipfile + 1733 | pfile_in_zip_read_info->byte_before_the_zipfile, 1734 | ZLIB_FILEFUNC_SEEK_SET)!=0) 1735 | return UNZ_ERRNO; 1736 | if (ZREAD64(pfile_in_zip_read_info->z_filefunc, 1737 | pfile_in_zip_read_info->filestream, 1738 | pfile_in_zip_read_info->read_buffer, 1739 | uReadThis)!=uReadThis) 1740 | return UNZ_ERRNO; 1741 | 1742 | 1743 | # ifndef NOUNCRYPT 1744 | if(s->encrypted) 1745 | { 1746 | uInt i; 1747 | for(i=0;iread_buffer[i] = 1749 | zdecode(s->keys,s->pcrc_32_tab, 1750 | pfile_in_zip_read_info->read_buffer[i]); 1751 | } 1752 | # endif 1753 | 1754 | 1755 | pfile_in_zip_read_info->pos_in_zipfile += uReadThis; 1756 | 1757 | pfile_in_zip_read_info->rest_read_compressed-=uReadThis; 1758 | 1759 | pfile_in_zip_read_info->stream.next_in = 1760 | (Bytef*)pfile_in_zip_read_info->read_buffer; 1761 | pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; 1762 | } 1763 | 1764 | if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) 1765 | { 1766 | uInt uDoCopy,i ; 1767 | 1768 | if ((pfile_in_zip_read_info->stream.avail_in == 0) && 1769 | (pfile_in_zip_read_info->rest_read_compressed == 0)) 1770 | return (iRead==0) ? UNZ_EOF : iRead; 1771 | 1772 | if (pfile_in_zip_read_info->stream.avail_out < 1773 | pfile_in_zip_read_info->stream.avail_in) 1774 | uDoCopy = pfile_in_zip_read_info->stream.avail_out ; 1775 | else 1776 | uDoCopy = pfile_in_zip_read_info->stream.avail_in ; 1777 | 1778 | for (i=0;istream.next_out+i) = 1780 | *(pfile_in_zip_read_info->stream.next_in+i); 1781 | 1782 | pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; 1783 | 1784 | pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, 1785 | pfile_in_zip_read_info->stream.next_out, 1786 | uDoCopy); 1787 | pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; 1788 | pfile_in_zip_read_info->stream.avail_in -= uDoCopy; 1789 | pfile_in_zip_read_info->stream.avail_out -= uDoCopy; 1790 | pfile_in_zip_read_info->stream.next_out += uDoCopy; 1791 | pfile_in_zip_read_info->stream.next_in += uDoCopy; 1792 | pfile_in_zip_read_info->stream.total_out += uDoCopy; 1793 | iRead += uDoCopy; 1794 | } 1795 | else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) 1796 | { 1797 | #ifdef HAVE_BZIP2 1798 | uLong uTotalOutBefore,uTotalOutAfter; 1799 | const Bytef *bufBefore; 1800 | uLong uOutThis; 1801 | 1802 | pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; 1803 | pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; 1804 | pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; 1805 | pfile_in_zip_read_info->bstream.total_in_hi32 = 0; 1806 | pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; 1807 | pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; 1808 | pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; 1809 | pfile_in_zip_read_info->bstream.total_out_hi32 = 0; 1810 | 1811 | uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; 1812 | bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; 1813 | 1814 | err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); 1815 | 1816 | uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; 1817 | uOutThis = uTotalOutAfter-uTotalOutBefore; 1818 | 1819 | pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; 1820 | 1821 | pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); 1822 | pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; 1823 | iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); 1824 | 1825 | pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; 1826 | pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; 1827 | pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; 1828 | pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; 1829 | pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; 1830 | pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; 1831 | 1832 | if (err==BZ_STREAM_END) 1833 | return (iRead==0) ? UNZ_EOF : iRead; 1834 | if (err!=BZ_OK) 1835 | break; 1836 | #endif 1837 | } // end Z_BZIP2ED 1838 | else 1839 | { 1840 | ZPOS64_T uTotalOutBefore,uTotalOutAfter; 1841 | const Bytef *bufBefore; 1842 | ZPOS64_T uOutThis; 1843 | int flush=Z_SYNC_FLUSH; 1844 | 1845 | uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; 1846 | bufBefore = pfile_in_zip_read_info->stream.next_out; 1847 | 1848 | /* 1849 | if ((pfile_in_zip_read_info->rest_read_uncompressed == 1850 | pfile_in_zip_read_info->stream.avail_out) && 1851 | (pfile_in_zip_read_info->rest_read_compressed == 0)) 1852 | flush = Z_FINISH; 1853 | */ 1854 | err=inflate(&pfile_in_zip_read_info->stream,flush); 1855 | 1856 | if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) 1857 | err = Z_DATA_ERROR; 1858 | 1859 | uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; 1860 | uOutThis = uTotalOutAfter-uTotalOutBefore; 1861 | 1862 | pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; 1863 | 1864 | pfile_in_zip_read_info->crc32 = 1865 | crc32(pfile_in_zip_read_info->crc32,bufBefore, 1866 | (uInt)(uOutThis)); 1867 | 1868 | pfile_in_zip_read_info->rest_read_uncompressed -= 1869 | uOutThis; 1870 | 1871 | iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); 1872 | 1873 | if (err==Z_STREAM_END) 1874 | return (iRead==0) ? UNZ_EOF : iRead; 1875 | if (err!=Z_OK) 1876 | break; 1877 | } 1878 | } 1879 | 1880 | if (err==Z_OK) 1881 | return iRead; 1882 | return err; 1883 | } 1884 | 1885 | 1886 | /* 1887 | Give the current position in uncompressed data 1888 | */ 1889 | extern z_off_t ZEXPORT unztell (unzFile file) 1890 | { 1891 | unz64_s* s; 1892 | file_in_zip64_read_info_s* pfile_in_zip_read_info; 1893 | if (file==NULL) 1894 | return UNZ_PARAMERROR; 1895 | s=(unz64_s*)file; 1896 | pfile_in_zip_read_info=s->pfile_in_zip_read; 1897 | 1898 | if (pfile_in_zip_read_info==NULL) 1899 | return UNZ_PARAMERROR; 1900 | 1901 | return (z_off_t)pfile_in_zip_read_info->stream.total_out; 1902 | } 1903 | 1904 | extern ZPOS64_T ZEXPORT unztell64 (unzFile file) 1905 | { 1906 | 1907 | unz64_s* s; 1908 | file_in_zip64_read_info_s* pfile_in_zip_read_info; 1909 | if (file==NULL) 1910 | return (ZPOS64_T)-1; 1911 | s=(unz64_s*)file; 1912 | pfile_in_zip_read_info=s->pfile_in_zip_read; 1913 | 1914 | if (pfile_in_zip_read_info==NULL) 1915 | return (ZPOS64_T)-1; 1916 | 1917 | return pfile_in_zip_read_info->total_out_64; 1918 | } 1919 | 1920 | 1921 | /* 1922 | return 1 if the end of file was reached, 0 elsewhere 1923 | */ 1924 | extern int ZEXPORT unzeof (unzFile file) 1925 | { 1926 | unz64_s* s; 1927 | file_in_zip64_read_info_s* pfile_in_zip_read_info; 1928 | if (file==NULL) 1929 | return UNZ_PARAMERROR; 1930 | s=(unz64_s*)file; 1931 | pfile_in_zip_read_info=s->pfile_in_zip_read; 1932 | 1933 | if (pfile_in_zip_read_info==NULL) 1934 | return UNZ_PARAMERROR; 1935 | 1936 | if (pfile_in_zip_read_info->rest_read_uncompressed == 0) 1937 | return 1; 1938 | else 1939 | return 0; 1940 | } 1941 | 1942 | 1943 | 1944 | /* 1945 | Read extra field from the current file (opened by unzOpenCurrentFile) 1946 | This is the local-header version of the extra field (sometimes, there is 1947 | more info in the local-header version than in the central-header) 1948 | 1949 | if buf==NULL, it return the size of the local extra field that can be read 1950 | 1951 | if buf!=NULL, len is the size of the buffer, the extra header is copied in 1952 | buf. 1953 | the return value is the number of bytes copied in buf, or (if <0) 1954 | the error code 1955 | */ 1956 | extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) 1957 | { 1958 | unz64_s* s; 1959 | file_in_zip64_read_info_s* pfile_in_zip_read_info; 1960 | uInt read_now; 1961 | ZPOS64_T size_to_read; 1962 | 1963 | if (file==NULL) 1964 | return UNZ_PARAMERROR; 1965 | s=(unz64_s*)file; 1966 | pfile_in_zip_read_info=s->pfile_in_zip_read; 1967 | 1968 | if (pfile_in_zip_read_info==NULL) 1969 | return UNZ_PARAMERROR; 1970 | 1971 | size_to_read = (pfile_in_zip_read_info->size_local_extrafield - 1972 | pfile_in_zip_read_info->pos_local_extrafield); 1973 | 1974 | if (buf==NULL) 1975 | return (int)size_to_read; 1976 | 1977 | if (len>size_to_read) 1978 | read_now = (uInt)size_to_read; 1979 | else 1980 | read_now = (uInt)len ; 1981 | 1982 | if (read_now==0) 1983 | return 0; 1984 | 1985 | if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, 1986 | pfile_in_zip_read_info->filestream, 1987 | pfile_in_zip_read_info->offset_local_extrafield + 1988 | pfile_in_zip_read_info->pos_local_extrafield, 1989 | ZLIB_FILEFUNC_SEEK_SET)!=0) 1990 | return UNZ_ERRNO; 1991 | 1992 | if (ZREAD64(pfile_in_zip_read_info->z_filefunc, 1993 | pfile_in_zip_read_info->filestream, 1994 | buf,read_now)!=read_now) 1995 | return UNZ_ERRNO; 1996 | 1997 | return (int)read_now; 1998 | } 1999 | 2000 | /* 2001 | Close the file in zip opened with unzipOpenCurrentFile 2002 | Return UNZ_CRCERROR if all the file was read but the CRC is not good 2003 | */ 2004 | extern int ZEXPORT unzCloseCurrentFile (unzFile file) 2005 | { 2006 | int err=UNZ_OK; 2007 | 2008 | unz64_s* s; 2009 | file_in_zip64_read_info_s* pfile_in_zip_read_info; 2010 | if (file==NULL) 2011 | return UNZ_PARAMERROR; 2012 | s=(unz64_s*)file; 2013 | pfile_in_zip_read_info=s->pfile_in_zip_read; 2014 | 2015 | if (pfile_in_zip_read_info==NULL) 2016 | return UNZ_PARAMERROR; 2017 | 2018 | 2019 | if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && 2020 | (!pfile_in_zip_read_info->raw)) 2021 | { 2022 | if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) 2023 | err=UNZ_CRCERROR; 2024 | } 2025 | 2026 | 2027 | TRYFREE(pfile_in_zip_read_info->read_buffer); 2028 | pfile_in_zip_read_info->read_buffer = NULL; 2029 | if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) 2030 | inflateEnd(&pfile_in_zip_read_info->stream); 2031 | #ifdef HAVE_BZIP2 2032 | else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) 2033 | BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); 2034 | #endif 2035 | 2036 | 2037 | pfile_in_zip_read_info->stream_initialised = 0; 2038 | TRYFREE(pfile_in_zip_read_info); 2039 | 2040 | s->pfile_in_zip_read=NULL; 2041 | 2042 | return err; 2043 | } 2044 | 2045 | 2046 | /* 2047 | Get the global comment string of the ZipFile, in the szComment buffer. 2048 | uSizeBuf is the size of the szComment buffer. 2049 | return the number of byte copied or an error code <0 2050 | */ 2051 | extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) 2052 | { 2053 | unz64_s* s; 2054 | uLong uReadThis ; 2055 | if (file==NULL) 2056 | return (int)UNZ_PARAMERROR; 2057 | s=(unz64_s*)file; 2058 | 2059 | uReadThis = uSizeBuf; 2060 | if (uReadThis>s->gi.size_comment) 2061 | uReadThis = s->gi.size_comment; 2062 | 2063 | if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) 2064 | return UNZ_ERRNO; 2065 | 2066 | if (uReadThis>0) 2067 | { 2068 | *szComment='\0'; 2069 | if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) 2070 | return UNZ_ERRNO; 2071 | } 2072 | 2073 | if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) 2074 | *(szComment+s->gi.size_comment)='\0'; 2075 | return (int)uReadThis; 2076 | } 2077 | 2078 | /* Additions by RX '2004 */ 2079 | extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) 2080 | { 2081 | unz64_s* s; 2082 | 2083 | if (file==NULL) 2084 | return 0; //UNZ_PARAMERROR; 2085 | s=(unz64_s*)file; 2086 | if (!s->current_file_ok) 2087 | return 0; 2088 | if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) 2089 | if (s->num_file==s->gi.number_entry) 2090 | return 0; 2091 | return s->pos_in_central_dir; 2092 | } 2093 | 2094 | extern uLong ZEXPORT unzGetOffset (unzFile file) 2095 | { 2096 | ZPOS64_T offset64; 2097 | 2098 | if (file==NULL) 2099 | return 0; //UNZ_PARAMERROR; 2100 | offset64 = unzGetOffset64(file); 2101 | return (uLong)offset64; 2102 | } 2103 | 2104 | extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) 2105 | { 2106 | unz64_s* s; 2107 | int err; 2108 | 2109 | if (file==NULL) 2110 | return UNZ_PARAMERROR; 2111 | s=(unz64_s*)file; 2112 | 2113 | s->pos_in_central_dir = pos; 2114 | s->num_file = s->gi.number_entry; /* hack */ 2115 | err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, 2116 | &s->cur_file_info_internal, 2117 | NULL,0,NULL,0,NULL,0); 2118 | s->current_file_ok = (err == UNZ_OK); 2119 | return err; 2120 | } 2121 | 2122 | extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) 2123 | { 2124 | return unzSetOffset64(file,pos); 2125 | } 2126 | --------------------------------------------------------------------------------