git subrepo clone https://github.com/libretro/libretro-common.git deps/libretro-common
[pcsx_rearmed.git] / deps / libretro-common / include / file / archive_file.h
1 /* Copyright  (C) 2010-2020 The RetroArch team
2  *
3  * ---------------------------------------------------------------------------------------
4  * The following license statement only applies to this file (archive_file.h).
5  * ---------------------------------------------------------------------------------------
6  *
7  * Permission is hereby granted, free of charge,
8  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
11  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22
23 #ifndef LIBRETRO_SDK_ARCHIVE_FILE_H__
24 #define LIBRETRO_SDK_ARCHIVE_FILE_H__
25
26 #include <stdint.h>
27 #include <stddef.h>
28 #include <boolean.h>
29
30 #ifdef _WIN32
31 #include <direct.h>
32 #else
33 #include <unistd.h>
34 #endif
35
36 #include <retro_miscellaneous.h>
37
38 #include <retro_common_api.h>
39
40 #if defined(RARCH_INTERNAL) && defined(HAVE_CONFIG_H)
41 #include "../../../config.h" /* for HAVE_MMAP */
42 #endif
43
44 RETRO_BEGIN_DECLS
45
46 enum file_archive_transfer_type
47 {
48    ARCHIVE_TRANSFER_NONE = 0,
49    ARCHIVE_TRANSFER_INIT,
50    ARCHIVE_TRANSFER_ITERATE,
51    ARCHIVE_TRANSFER_DEINIT,
52    ARCHIVE_TRANSFER_DEINIT_ERROR
53 };
54
55 typedef struct file_archive_handle
56 {
57    uint8_t  *data;
58    uint32_t real_checksum;
59 } file_archive_file_handle_t;
60
61 typedef struct file_archive_transfer
62 {
63    int64_t archive_size;
64    void *context;
65    struct RFILE *archive_file;
66    const struct file_archive_file_backend *backend;
67 #ifdef HAVE_MMAP
68    uint8_t *archive_mmap_data;
69    int archive_mmap_fd;
70 #endif
71    unsigned step_total;
72    unsigned step_current;
73    enum file_archive_transfer_type type;
74 } file_archive_transfer_t;
75
76 typedef struct
77 {
78    file_archive_transfer_t archive;             /* int64_t alignment */
79    char *source_file;
80    char *subdir;
81    char *target_dir;
82    char *target_file;
83    char *valid_ext;
84    char *callback_error;
85    struct archive_extract_userdata *userdata;
86 } decompress_state_t;
87
88 struct archive_extract_userdata
89 {
90    /* These are set or read by the archive processing */
91    char *first_extracted_file_path;
92    const char *extraction_directory;
93    struct string_list *ext;
94    struct string_list *list;
95    file_archive_transfer_t *transfer;
96    /* Not used by the processing, free to use outside or in iterate callback */
97    decompress_state_t *dec;
98    void* cb_data;
99    uint32_t crc;
100    char archive_path[PATH_MAX_LENGTH];
101    char current_file_path[PATH_MAX_LENGTH];
102    bool found_file;
103    bool list_only;
104 };
105
106 /* Returns true when parsing should continue. False to stop. */
107 typedef int (*file_archive_file_cb)(const char *name, const char *valid_exts,
108       const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
109       uint32_t crc32, struct archive_extract_userdata *userdata);
110
111 struct file_archive_file_backend
112 {
113    int (*archive_parse_file_init)(
114       file_archive_transfer_t *state,
115       const char *file);
116    int (*archive_parse_file_iterate_step)(
117       void *context,
118       const char *valid_exts,
119       struct archive_extract_userdata *userdata,
120       file_archive_file_cb file_cb);
121    void (*archive_parse_file_free)(
122       void *context);
123
124    bool     (*stream_decompress_data_to_file_init)(
125       void *context, file_archive_file_handle_t *handle,
126       const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size);
127    int      (*stream_decompress_data_to_file_iterate)(
128       void *context,
129       file_archive_file_handle_t *handle);
130
131    uint32_t (*stream_crc_calculate)(uint32_t, const uint8_t *, size_t);
132    int64_t (*compressed_file_read)(const char *path, const char *needle, void **buf,
133          const char *optional_outfile);
134    const char *ident;
135 };
136
137 int file_archive_parse_file_iterate(
138       file_archive_transfer_t *state,
139       bool *returnerr,
140       const char *file,
141       const char *valid_exts,
142       file_archive_file_cb file_cb,
143       struct archive_extract_userdata *userdata);
144
145 void file_archive_parse_file_iterate_stop(file_archive_transfer_t *state);
146
147 int file_archive_parse_file_progress(file_archive_transfer_t *state);
148
149 /**
150  * file_archive_extract_file:
151  * @archive_path                : filename path to ZIP archive.
152  * @valid_exts                  : valid extensions for a file.
153  * @extraction_directory        : the directory to extract the temporary
154  *                                file to.
155  *
156  * Extract file from archive. If no file inside the archive is
157  * specified, the first file found will be used.
158  *
159  * Returns : true (1) on success, otherwise false (0).
160  **/
161 bool file_archive_extract_file(const char *archive_path,
162       const char *valid_exts, const char *extraction_dir,
163       char *out_path, size_t len);
164
165 /* Warning: 'list' must zero initialised before
166  * calling this function, otherwise memory leaks/
167  * undefined behaviour will occur */
168 bool file_archive_get_file_list_noalloc(struct string_list *list,
169       const char *path,
170       const char *valid_exts);
171
172 /**
173  * file_archive_get_file_list:
174  * @path                        : filename path of archive
175  * @valid_exts                  : Valid extensions of archive to be parsed.
176  *                                If NULL, allow all.
177  *
178  * Returns: string listing of files from archive on success, otherwise NULL.
179  **/
180 struct string_list* file_archive_get_file_list(const char *path, const char *valid_exts);
181
182 bool file_archive_perform_mode(const char *name, const char *valid_exts,
183       const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
184       uint32_t crc32, struct archive_extract_userdata *userdata);
185
186 int file_archive_compressed_read(
187       const char* path, void **buf,
188       const char* optional_filename, int64_t *length);
189
190 const struct file_archive_file_backend* file_archive_get_zlib_file_backend(void);
191 const struct file_archive_file_backend* file_archive_get_7z_file_backend(void);
192
193 const struct file_archive_file_backend* file_archive_get_file_backend(const char *path);
194
195 /**
196  * file_archive_get_file_crc32:
197  * @path                         : filename path of archive
198  *
199  * Returns: CRC32 of the specified file in the archive, otherwise 0.
200  * If no path within the archive is specified, the first
201  * file found inside is used.
202  **/
203 uint32_t file_archive_get_file_crc32(const char *path);
204
205 extern const struct file_archive_file_backend zlib_backend;
206 extern const struct file_archive_file_backend sevenzip_backend;
207
208 RETRO_END_DECLS
209
210 #endif