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*/
9fz_stream *
10fz_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*/
24fz_buffer *
25fz_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*/
41int
42fz_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*/
56const char *
57fz_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*/
69int
70fz_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
77const char *
78fz_archive_format(fz_context *ctx, fz_archive *arch)
79{
80 return arch->format;
81}
82
83fz_archive *
84fz_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*/
98fz_archive *
99fz_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*/
121fz_archive *
122fz_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
139void
140fz_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