1 /** Uniform access to zip, gzip, 7-zip, and RAR compressed archives \file */ 2 3 /* File_Extractor 1.0.0 */ 4 #ifndef FEX_H 5 #define FEX_H 6 7 #include <stddef.h> 8 9 #ifdef __cplusplus 10 extern "C" { 11 #endif 12 13 14 /** First parameter of most functions is fex_t*, or const fex_t* if nothing is 15 changed. Once one of these functions returns an error, the archive should not 16 be used any further, other than to close it. One exception is 17 fex_error_file_eof; the archive may still be used after this. */ 18 typedef struct fex_t fex_t; 19 20 /** Pointer to error, or NULL if function was successful. See error functions 21 below. */ 22 #ifndef fex_err_t /* (#ifndef allows better testing of library) */ 23 typedef const char* fex_err_t; 24 #endif 25 26 27 /**** File types ****/ 28 29 /** Archive file type identifier. Can also hold NULL. */ 30 typedef const struct fex_type_t_* fex_type_t; 31 32 /** Array of supported types, with NULL at end */ 33 const fex_type_t* fex_type_list( void ); 34 35 /** Name of this archive type, e.g. "ZIP archive", "file" */ 36 const char* fex_type_name( fex_type_t ); 37 38 /** Usual file extension for type, e.g. ".zip", ".7z". For binary file type, 39 returns "", since it can open any file. */ 40 const char* fex_type_extension( fex_type_t ); 41 42 43 /**** Wide-character file paths ****/ 44 45 /** Converts wide-character path to form suitable for use with fex functions. */ 46 char* fex_wide_to_path( const wchar_t* wide ); 47 48 /** Frees converted path. OK to pass NULL. */ 49 void fex_free_path( char* ); 50 51 52 /**** Identification ****/ 53 54 /** True if str ends in extension. If extension is "", always returns true. 55 Converts str to lowercase before comparison, so extension should ALREADY be 56 lowercase (i.e. pass ".zip", NOT ".ZIP"). */ 57 int fex_has_extension( const char str [], const char extension [] ); 58 59 /** Determines type based on first fex_identify_header_size bytes of file. 60 Returns usual file extension this should have (e.g. ".zip", ".gz", etc.). 61 Returns "" if file header is not recognized. */ 62 const char* fex_identify_header( const void* header ); 63 enum { fex_identify_header_size = 16 }; 64 65 /** Determines type based on extension of a file path, or just a lone extension 66 (must include '.', e.g. ".zip", NOT just "zip"). Returns NULL if extension is 67 for an unsupported type (e.g. ".lzh"). */ 68 fex_type_t fex_identify_extension( const char path_or_extension [] ); 69 70 /** Determines type based on filename extension and/or file header. Sets *out 71 to determined type, or NULL if type is not supported. */ 72 fex_err_t fex_identify_file( fex_type_t* out, const char path [] ); 73 74 /** Type of an already-opened archive */ 75 fex_type_t fex_type( const fex_t* ); 76 77 78 /**** Open/close ****/ 79 80 /** Initializes static tables used by library. Automatically called by 81 fex_open(). OK to call more than once. */ 82 fex_err_t fex_init( void ); 83 84 /** Opens archive and points *out at it. If error, sets *out to NULL. */ 85 fex_err_t fex_open( fex_t** out, const char path [] ); 86 87 /** Opens archive of specified type and sets *out. Returns error if file is not 88 of that archive type. If error, sets *out to NULL. */ 89 fex_err_t fex_open_type( fex_t** out, const char path [], fex_type_t ); 90 91 /** Closes archive and frees memory. OK to pass NULL. */ 92 void fex_close( fex_t* ); 93 94 95 /**** Scanning ****/ 96 97 /** True if at end of archive. Must be called after fex_open() or fex_rewind(), 98 as an archive might contain no files. */ 99 int fex_done( const fex_t* ); 100 101 /** Goes to next file in archive. If there are no more files, fex_done() will 102 now return true. */ 103 fex_err_t fex_next( fex_t* ); 104 105 /** Goes back to first file in archive, as if it were just opened with 106 fex_open() */ 107 fex_err_t fex_rewind( fex_t* ); 108 109 /** Saved position in archive. Can also store zero. */ 110 typedef int fex_pos_t; 111 112 /** Position of current file in archive. Never returns zero. */ 113 fex_pos_t fex_tell_arc( const fex_t* ); 114 115 /** Returns to file at previously-saved position */ 116 fex_err_t fex_seek_arc( fex_t*, fex_pos_t ); 117 118 119 /**** Info ****/ 120 121 /** Name of current file */ 122 const char* fex_name( const fex_t* ); 123 124 /** Wide-character name of current file, or NULL if unavailable */ 125 const wchar_t* fex_wname( const fex_t* ); 126 127 /** Makes further information available for file */ 128 fex_err_t fex_stat( fex_t* ); 129 130 /** Size of current file. fex_stat() or fex_data() must have been called. */ 131 int fex_size( const fex_t* ); 132 133 /** Modification date of current file (MS-DOS format), or 0 if unavailable. 134 fex_stat() must have been called. */ 135 unsigned int fex_dos_date( const fex_t* ); 136 137 /** CRC-32 checksum of current file's contents, or 0 if unavailable. Doesn't 138 require calculation; simply gets it from file's header. fex_stat() must have 139 been called. */ 140 unsigned int fex_crc32( const fex_t* ); 141 142 143 /**** Extraction ****/ 144 145 /** Reads n bytes from current file. Reading past end of file results in 146 fex_err_file_eof. */ 147 fex_err_t fex_read( fex_t*, void* out, int n ); 148 149 /** Number of bytes read from current file */ 150 int fex_tell( const fex_t* ); 151 152 /** Points *out at current file's data in memory. Pointer is valid until 153 fex_next(), fex_rewind(), fex_seek_arc(), or fex_close() is called. Pointer 154 must NOT be freed(); library frees it automatically. If error, sets *out to 155 NULL. */ 156 fex_err_t fex_data( fex_t*, const void** out ); 157 158 159 /**** Errors ****/ 160 161 /** Error string associated with err. Returns "" if err is NULL. Returns err 162 unchanged if it isn't a fex_err_t returned by library. */ 163 const char* fex_err_str( fex_err_t err ); 164 165 /** Details of error beyond main cause, or "" if none or err is NULL. Returns 166 err unchanged if it isn't a fex_err_t returned by library. */ 167 const char* fex_err_details( fex_err_t err ); 168 169 /** Numeric code corresponding to err. Returns fex_ok if err is NULL. Returns 170 fex_err_generic if err isn't a fex_err_t returned by library. */ 171 int fex_err_code( fex_err_t err ); 172 173 enum { 174 fex_ok = 0,/**< Successful call. Guaranteed to be zero. */ 175 fex_err_generic = 0x01,/**< Error of unspecified type */ 176 fex_err_memory = 0x02,/**< Out of memory */ 177 fex_err_caller = 0x03,/**< Caller called function with bad args */ 178 fex_err_internal = 0x04,/**< Internal problem, bug, etc. */ 179 fex_err_limitation = 0x05,/**< Exceeded program limit */ 180 181 fex_err_file_missing = 0x20,/**< File not found at specified path */ 182 fex_err_file_read = 0x21,/**< Couldn't open file for reading */ 183 fex_err_file_io = 0x23,/**< Read/write error */ 184 fex_err_file_eof = 0x25,/**< Tried to read past end of file */ 185 186 fex_err_file_type = 0x30,/**< File is of wrong type */ 187 fex_err_file_feature = 0x32,/**< File requires unsupported feature */ 188 fex_err_file_corrupt = 0x33 /**< File is corrupt */ 189 }; 190 191 /** fex_err_t corresponding to numeric code. Note that this might not recover 192 the original fex_err_t before it was converted to a numeric code; in 193 particular, fex_err_details(fex_code_to_err(code)) will be "" in most cases. */ 194 fex_err_t fex_code_to_err( int code ); 195 196 197 /* Deprecated */ 198 typedef fex_t File_Extractor; 199 200 #ifdef __cplusplus 201 } 202 #endif 203 204 #endif 205