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