1 /* Copyright 2015 the unarr project authors (see AUTHORS file).
2    License: LGPLv3 */
3 
4 #ifndef unarr_h
5 #define unarr_h
6 
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 
11 #include <stddef.h>
12 #include <stdint.h>
13 #include <stdbool.h>
14 
15 
16 /* macros for shared library usage */
17 
18 #if defined (UNARR_IS_SHARED_LIBRARY)
19 #if defined (_WIN32)
20 
21 #if defined (UNARR_EXPORT_SYMBOLS)
22 #define UNARR_EXPORT __declspec(dllexport)
23 #else
24 #define UNARR_EXPORT __declspec(dllimport)
25 #endif // UNARR_EXPORT_SYMBOLS
26 
27 #else // _WIN32
28 
29 #if defined (UNARR_EXPORT_SYMBOLS)
30 #define UNARR_EXPORT __attribute__((visibility("default")))
31 #else
32 #define UNARR_EXPORT
33 #endif // UNARR_EXPORT_SYMBOLS
34 #endif // _WIN32
35 
36 #else // defined UNARR_IS_SHARED_LIBRARY
37 #define UNARR_EXPORT
38 
39 #endif // UNARR_IS_SHARED_LIBRARY
40 
41 
42 typedef int64_t off64_t;
43 typedef int64_t time64_t;
44 
45 #define UNARR_API_VERSION 100
46 
47 /***** common/stream *****/
48 
49 typedef struct ar_stream_s ar_stream;
50 
51 /* opens a read-only stream for the given file path; returns NULL on error */
52 UNARR_EXPORT ar_stream *ar_open_file(const char *path);
53 #ifdef _WIN32
54 UNARR_EXPORT ar_stream *ar_open_file_w(const wchar_t *path);
55 #endif
56 /* opens a read-only stream for the given chunk of memory; the pointer must be valid until ar_close is called */
57 UNARR_EXPORT ar_stream *ar_open_memory(const void *data, size_t datalen);
58 #ifdef _WIN32
59 typedef struct IStream IStream;
60 /* opens a read-only stream based on the given IStream */
61 UNARR_EXPORT ar_stream *ar_open_istream(IStream *stream);
62 #endif
63 
64 /* closes the stream and releases underlying resources */
65 UNARR_EXPORT void ar_close(ar_stream *stream);
66 /* tries to read 'count' bytes into buffer, advancing the read offset pointer; returns the actual number of bytes read */
67 UNARR_EXPORT size_t ar_read(ar_stream *stream, void *buffer, size_t count);
68 /* moves the read offset pointer (same as fseek); returns false on failure */
69 UNARR_EXPORT bool ar_seek(ar_stream *stream, off64_t offset, int origin);
70 /* shortcut for ar_seek(stream, count, SEEK_CUR); returns false on failure */
71 UNARR_EXPORT bool ar_skip(ar_stream *stream, off64_t count);
72 /* returns the current read offset (or 0 on error) */
73 UNARR_EXPORT off64_t ar_tell(ar_stream *stream);
74 
75 /***** common/unarr *****/
76 
77 typedef struct ar_archive_s ar_archive;
78 
79 /* frees all data stored for the given archive; does not close the underlying stream */
80 UNARR_EXPORT void ar_close_archive(ar_archive *ar);
81 /* reads the next archive entry; returns false on error or at the end of the file (use ar_at_eof to distinguish the two cases) */
82 UNARR_EXPORT bool ar_parse_entry(ar_archive *ar);
83 /* reads the archive entry at the given offset as returned by ar_entry_get_offset (offset 0 always restarts at the first entry); should always succeed */
84 UNARR_EXPORT bool ar_parse_entry_at(ar_archive *ar, off64_t offset);
85 /* reads the (first) archive entry associated with the given name; returns false if the entry couldn't be found */
86 UNARR_EXPORT bool ar_parse_entry_for(ar_archive *ar, const char *entry_name);
87 /* returns whether the last ar_parse_entry call has reached the file's expected end */
88 UNARR_EXPORT bool ar_at_eof(ar_archive *ar);
89 
90 /* returns the name of the current entry as UTF-8 string; this pointer is only valid until the next call to ar_parse_entry; returns NULL on failure */
91 UNARR_EXPORT const char *ar_entry_get_name(ar_archive *ar);
92 /* returns the stream offset of the current entry for use with ar_parse_entry_at */
93 UNARR_EXPORT off64_t ar_entry_get_offset(ar_archive *ar);
94 /* returns the total size of uncompressed data of the current entry; read exactly that many bytes using ar_entry_uncompress */
95 UNARR_EXPORT size_t ar_entry_get_size(ar_archive *ar);
96 /* returns the stored modification date of the current entry in 100ns since 1601/01/01 */
97 UNARR_EXPORT time64_t ar_entry_get_filetime(ar_archive *ar);
98 /* WARNING: don't manually seek in the stream between ar_parse_entry and the last corresponding ar_entry_uncompress call! */
99 /* uncompresses the next 'count' bytes of the current entry into buffer; returns false on error */
100 UNARR_EXPORT bool ar_entry_uncompress(ar_archive *ar, void *buffer, size_t count);
101 
102 /* copies at most 'count' bytes of the archive's global comment (if any) into buffer; returns the actual amout of bytes copied (or, if 'buffer' is NULL, the required buffer size) */
103 UNARR_EXPORT size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count);
104 
105 /***** rar/rar *****/
106 
107 /* checks whether 'stream' could contain RAR data and prepares for archive listing/extraction; returns NULL on failure */
108 UNARR_EXPORT ar_archive *ar_open_rar_archive(ar_stream *stream);
109 
110 /***** tar/tar *****/
111 
112 /* checks whether 'stream' could contain TAR data and prepares for archive listing/extraction; returns NULL on failure */
113 UNARR_EXPORT ar_archive *ar_open_tar_archive(ar_stream *stream);
114 
115 /***** zip/zip *****/
116 
117 /* checks whether 'stream' could contain ZIP data and prepares for archive listing/extraction; returns NULL on failure */
118 /* set deflatedonly for extracting XPS, EPUB, etc. documents where non-Deflate compression methods are not supported by specification */
119 UNARR_EXPORT ar_archive *ar_open_zip_archive(ar_stream *stream, bool deflatedonly);
120 
121 /***** _7z/_7z *****/
122 
123 /* checks whether 'stream' could contain 7Z data and prepares for archive listing/extraction; returns NULL on failure */
124 UNARR_EXPORT ar_archive *ar_open_7z_archive(ar_stream *stream);
125 
126 #ifdef __cplusplus
127 }
128 #endif
129 
130 #endif //unarr_h
131