1 | #include "mupdf/fitz.h" |
2 | |
3 | /* |
4 | Opens an archive entry as a stream. |
5 | |
6 | name: Entry name to look for, this must be an exact match to |
7 | the entry name in the archive. |
8 | */ |
9 | fz_stream * |
10 | fz_open_archive_entry(fz_context *ctx, fz_archive *arch, const char *name) |
11 | { |
12 | if (!arch->open_entry) |
13 | fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open archive entry" ); |
14 | return arch->open_entry(ctx, arch, name); |
15 | } |
16 | |
17 | /* |
18 | Reads all bytes in an archive entry |
19 | into a buffer. |
20 | |
21 | name: Entry name to look for, this must be an exact match to |
22 | the entry name in the archive. |
23 | */ |
24 | fz_buffer * |
25 | fz_read_archive_entry(fz_context *ctx, fz_archive *arch, const char *name) |
26 | { |
27 | if (!arch->read_entry) |
28 | fz_throw(ctx, FZ_ERROR_GENERIC, "cannot read archive entry" ); |
29 | return arch->read_entry(ctx, arch, name); |
30 | } |
31 | |
32 | /* |
33 | Check if entry by given name exists. |
34 | |
35 | If named entry does not exist 0 will be returned, if it does |
36 | exist 1 is returned. |
37 | |
38 | name: Entry name to look for, this must be an exact match to |
39 | the entry name in the archive. |
40 | */ |
41 | int |
42 | fz_has_archive_entry(fz_context *ctx, fz_archive *arch, const char *name) |
43 | { |
44 | if (!arch->has_entry) |
45 | fz_throw(ctx, FZ_ERROR_GENERIC, "cannot check if archive has entry" ); |
46 | return arch->has_entry(ctx, arch, name); |
47 | } |
48 | |
49 | /* |
50 | Get listed name of entry position idx. |
51 | |
52 | idx: Must be a value >= 0 < return value from |
53 | fz_count_archive_entries. If not in range NULL will be |
54 | returned. |
55 | */ |
56 | const char * |
57 | fz_list_archive_entry(fz_context *ctx, fz_archive *arch, int idx) |
58 | { |
59 | if (!arch->list_entry) |
60 | fz_throw(ctx, FZ_ERROR_GENERIC, "cannot list archive entries" ); |
61 | return arch->list_entry(ctx, arch, idx); |
62 | } |
63 | |
64 | /* |
65 | Number of entries in archive. |
66 | |
67 | Will always return a value >= 0. |
68 | */ |
69 | int |
70 | fz_count_archive_entries(fz_context *ctx, fz_archive *arch) |
71 | { |
72 | if (!arch->count_entries) |
73 | fz_throw(ctx, FZ_ERROR_GENERIC, "cannot count archive entries" ); |
74 | return arch->count_entries(ctx, arch); |
75 | } |
76 | |
77 | const char * |
78 | fz_archive_format(fz_context *ctx, fz_archive *arch) |
79 | { |
80 | return arch->format; |
81 | } |
82 | |
83 | fz_archive * |
84 | fz_new_archive_of_size(fz_context *ctx, fz_stream *file, int size) |
85 | { |
86 | fz_archive *arch; |
87 | arch = Memento_label(fz_calloc(ctx, 1, size), "fz_archive" ); |
88 | arch->file = fz_keep_stream(ctx, file); |
89 | return arch; |
90 | } |
91 | |
92 | /* |
93 | Open zip or tar archive stream. |
94 | |
95 | Open an archive using a seekable stream object rather than |
96 | opening a file or directory on disk. |
97 | */ |
98 | fz_archive * |
99 | fz_open_archive_with_stream(fz_context *ctx, fz_stream *file) |
100 | { |
101 | fz_archive *arch = NULL; |
102 | |
103 | if (fz_is_zip_archive(ctx, file)) |
104 | arch = fz_open_zip_archive_with_stream(ctx, file); |
105 | else if (fz_is_tar_archive(ctx, file)) |
106 | arch = fz_open_tar_archive_with_stream(ctx, file); |
107 | else |
108 | fz_throw(ctx, FZ_ERROR_GENERIC, "cannot recognize archive" ); |
109 | |
110 | return arch; |
111 | } |
112 | |
113 | /* |
114 | Open a zip or tar archive |
115 | |
116 | Open a file and identify its archive type based on the archive |
117 | signature contained inside. |
118 | |
119 | filename: a path to a file as it would be given to open(2). |
120 | */ |
121 | fz_archive * |
122 | fz_open_archive(fz_context *ctx, const char *filename) |
123 | { |
124 | fz_stream *file; |
125 | fz_archive *arch = NULL; |
126 | |
127 | file = fz_open_file(ctx, filename); |
128 | |
129 | fz_try(ctx) |
130 | arch = fz_open_archive_with_stream(ctx, file); |
131 | fz_always(ctx) |
132 | fz_drop_stream(ctx, file); |
133 | fz_catch(ctx) |
134 | fz_rethrow(ctx); |
135 | |
136 | return arch; |
137 | } |
138 | |
139 | void |
140 | fz_drop_archive(fz_context *ctx, fz_archive *arch) |
141 | { |
142 | if (!arch) |
143 | return; |
144 | |
145 | if (arch->drop_archive) |
146 | arch->drop_archive(ctx, arch); |
147 | fz_drop_stream(ctx, arch->file); |
148 | fz_free(ctx, arch); |
149 | } |
150 | |