xref: /aosp_15_r20/system/libziparchive/include/ziparchive/zip_archive.h (revision adcb0a6279ea715828f9bc5e351569419e478774)
1*adcb0a62SAndroid Build Coastguard Worker /*
2*adcb0a62SAndroid Build Coastguard Worker  * Copyright (C) 2013 The Android Open Source Project
3*adcb0a62SAndroid Build Coastguard Worker  *
4*adcb0a62SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*adcb0a62SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*adcb0a62SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*adcb0a62SAndroid Build Coastguard Worker  *
8*adcb0a62SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*adcb0a62SAndroid Build Coastguard Worker  *
10*adcb0a62SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*adcb0a62SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*adcb0a62SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*adcb0a62SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*adcb0a62SAndroid Build Coastguard Worker  * limitations under the License.
15*adcb0a62SAndroid Build Coastguard Worker  */
16*adcb0a62SAndroid Build Coastguard Worker 
17*adcb0a62SAndroid Build Coastguard Worker #pragma once
18*adcb0a62SAndroid Build Coastguard Worker 
19*adcb0a62SAndroid Build Coastguard Worker /*
20*adcb0a62SAndroid Build Coastguard Worker  * Read-only access to Zip archives, with minimal heap allocation.
21*adcb0a62SAndroid Build Coastguard Worker  */
22*adcb0a62SAndroid Build Coastguard Worker 
23*adcb0a62SAndroid Build Coastguard Worker #include <stdint.h>
24*adcb0a62SAndroid Build Coastguard Worker #include <string.h>
25*adcb0a62SAndroid Build Coastguard Worker #include <sys/cdefs.h>
26*adcb0a62SAndroid Build Coastguard Worker #include <sys/types.h>
27*adcb0a62SAndroid Build Coastguard Worker 
28*adcb0a62SAndroid Build Coastguard Worker #include <functional>
29*adcb0a62SAndroid Build Coastguard Worker #include <string>
30*adcb0a62SAndroid Build Coastguard Worker #include <string_view>
31*adcb0a62SAndroid Build Coastguard Worker #include <utility>
32*adcb0a62SAndroid Build Coastguard Worker 
33*adcb0a62SAndroid Build Coastguard Worker #include "android-base/macros.h"
34*adcb0a62SAndroid Build Coastguard Worker #include "android-base/off64_t.h"
35*adcb0a62SAndroid Build Coastguard Worker 
36*adcb0a62SAndroid Build Coastguard Worker /* Zip compression methods we support */
37*adcb0a62SAndroid Build Coastguard Worker enum {
38*adcb0a62SAndroid Build Coastguard Worker   kCompressStored = 0,    // no compression
39*adcb0a62SAndroid Build Coastguard Worker   kCompressDeflated = 8,  // standard deflate
40*adcb0a62SAndroid Build Coastguard Worker };
41*adcb0a62SAndroid Build Coastguard Worker 
42*adcb0a62SAndroid Build Coastguard Worker // This struct holds the common information of a zip entry other than the
43*adcb0a62SAndroid Build Coastguard Worker // the entry size. The compressed and uncompressed length will be handled
44*adcb0a62SAndroid Build Coastguard Worker // separately in the derived class.
45*adcb0a62SAndroid Build Coastguard Worker struct ZipEntryCommon {
46*adcb0a62SAndroid Build Coastguard Worker   // Compression method. One of kCompressStored or kCompressDeflated.
47*adcb0a62SAndroid Build Coastguard Worker   // See also `gpbf` for deflate subtypes.
48*adcb0a62SAndroid Build Coastguard Worker   uint16_t method;
49*adcb0a62SAndroid Build Coastguard Worker 
50*adcb0a62SAndroid Build Coastguard Worker   // Modification time. The zipfile format specifies
51*adcb0a62SAndroid Build Coastguard Worker   // that the first two little endian bytes contain the time
52*adcb0a62SAndroid Build Coastguard Worker   // and the last two little endian bytes contain the date.
53*adcb0a62SAndroid Build Coastguard Worker   // See `GetModificationTime`. Use signed integer to avoid the
54*adcb0a62SAndroid Build Coastguard Worker   // sub-overflow.
55*adcb0a62SAndroid Build Coastguard Worker   // TODO: should be overridden by extra time field, if present.
56*adcb0a62SAndroid Build Coastguard Worker   int32_t mod_time;
57*adcb0a62SAndroid Build Coastguard Worker 
58*adcb0a62SAndroid Build Coastguard Worker   // Returns `mod_time` as a broken-down struct tm.
59*adcb0a62SAndroid Build Coastguard Worker   struct tm GetModificationTime() const;
60*adcb0a62SAndroid Build Coastguard Worker 
61*adcb0a62SAndroid Build Coastguard Worker   // Suggested Unix mode for this entry, from the zip archive if created on
62*adcb0a62SAndroid Build Coastguard Worker   // Unix, or a default otherwise. See also `external_file_attributes`.
63*adcb0a62SAndroid Build Coastguard Worker   mode_t unix_mode;
64*adcb0a62SAndroid Build Coastguard Worker 
65*adcb0a62SAndroid Build Coastguard Worker   // 1 if this entry contains a data descriptor segment, 0
66*adcb0a62SAndroid Build Coastguard Worker   // otherwise.
67*adcb0a62SAndroid Build Coastguard Worker   uint8_t has_data_descriptor;
68*adcb0a62SAndroid Build Coastguard Worker 
69*adcb0a62SAndroid Build Coastguard Worker   // Crc32 value of this ZipEntry. This information might
70*adcb0a62SAndroid Build Coastguard Worker   // either be stored in the local file header or in a special
71*adcb0a62SAndroid Build Coastguard Worker   // Data descriptor footer at the end of the file entry.
72*adcb0a62SAndroid Build Coastguard Worker   uint32_t crc32;
73*adcb0a62SAndroid Build Coastguard Worker 
74*adcb0a62SAndroid Build Coastguard Worker   // If the value of uncompressed length and compressed length are stored in
75*adcb0a62SAndroid Build Coastguard Worker   // the zip64 extended info of the extra field.
76*adcb0a62SAndroid Build Coastguard Worker   bool zip64_format_size{false};
77*adcb0a62SAndroid Build Coastguard Worker 
78*adcb0a62SAndroid Build Coastguard Worker   // The offset to the start of data for this ZipEntry.
79*adcb0a62SAndroid Build Coastguard Worker   off64_t offset;
80*adcb0a62SAndroid Build Coastguard Worker 
81*adcb0a62SAndroid Build Coastguard Worker   // The version of zip and the host file system this came from (for zipinfo).
82*adcb0a62SAndroid Build Coastguard Worker   uint16_t version_made_by;
83*adcb0a62SAndroid Build Coastguard Worker 
84*adcb0a62SAndroid Build Coastguard Worker   // The raw attributes, whose interpretation depends on the host
85*adcb0a62SAndroid Build Coastguard Worker   // file system in `version_made_by` (for zipinfo). See also `unix_mode`.
86*adcb0a62SAndroid Build Coastguard Worker   uint32_t external_file_attributes;
87*adcb0a62SAndroid Build Coastguard Worker 
88*adcb0a62SAndroid Build Coastguard Worker   // Specifics about the deflation (for zipinfo).
89*adcb0a62SAndroid Build Coastguard Worker   uint16_t gpbf;
90*adcb0a62SAndroid Build Coastguard Worker   // Whether this entry is believed to be text or binary (for zipinfo).
91*adcb0a62SAndroid Build Coastguard Worker   bool is_text;
92*adcb0a62SAndroid Build Coastguard Worker 
93*adcb0a62SAndroid Build Coastguard Worker   // extra field size
94*adcb0a62SAndroid Build Coastguard Worker   uint16_t extra_field_size;
95*adcb0a62SAndroid Build Coastguard Worker };
96*adcb0a62SAndroid Build Coastguard Worker 
97*adcb0a62SAndroid Build Coastguard Worker struct ZipEntry64;
98*adcb0a62SAndroid Build Coastguard Worker // Many users of the library assume the entry size is capped at UINT32_MAX. So we keep
99*adcb0a62SAndroid Build Coastguard Worker // the interface for the old ZipEntry here; and we could switch them over to the new
100*adcb0a62SAndroid Build Coastguard Worker // ZipEntry64 later.
101*adcb0a62SAndroid Build Coastguard Worker struct ZipEntry : public ZipEntryCommon {
102*adcb0a62SAndroid Build Coastguard Worker   // Compressed length of this ZipEntry. The maximum value is UINT32_MAX.
103*adcb0a62SAndroid Build Coastguard Worker   // Might be present either in the local file header or in the data
104*adcb0a62SAndroid Build Coastguard Worker   // descriptor footer.
105*adcb0a62SAndroid Build Coastguard Worker   uint32_t compressed_length{0};
106*adcb0a62SAndroid Build Coastguard Worker 
107*adcb0a62SAndroid Build Coastguard Worker   // Uncompressed length of this ZipEntry. The maximum value is UINT32_MAX.
108*adcb0a62SAndroid Build Coastguard Worker   // Might be present either in the local file header or in the data
109*adcb0a62SAndroid Build Coastguard Worker   // descriptor footer.
110*adcb0a62SAndroid Build Coastguard Worker   uint32_t uncompressed_length{0};
111*adcb0a62SAndroid Build Coastguard Worker 
112*adcb0a62SAndroid Build Coastguard Worker   // Copies the contents of a ZipEntry64 object to a 32 bits ZipEntry. Returns 0 if the
113*adcb0a62SAndroid Build Coastguard Worker   // size of the entry fits into uint32_t, returns a negative error code
114*adcb0a62SAndroid Build Coastguard Worker   // (kUnsupportedEntrySize) otherwise.
115*adcb0a62SAndroid Build Coastguard Worker   static int32_t CopyFromZipEntry64(ZipEntry* dst, const ZipEntry64* src);
116*adcb0a62SAndroid Build Coastguard Worker 
117*adcb0a62SAndroid Build Coastguard Worker  private:
118*adcb0a62SAndroid Build Coastguard Worker   ZipEntry& operator=(const ZipEntryCommon& other) {
119*adcb0a62SAndroid Build Coastguard Worker     ZipEntryCommon::operator=(other);
120*adcb0a62SAndroid Build Coastguard Worker     return *this;
121*adcb0a62SAndroid Build Coastguard Worker   }
122*adcb0a62SAndroid Build Coastguard Worker };
123*adcb0a62SAndroid Build Coastguard Worker 
124*adcb0a62SAndroid Build Coastguard Worker // Represents information about a zip entry in a zip file.
125*adcb0a62SAndroid Build Coastguard Worker struct ZipEntry64 : public ZipEntryCommon {
126*adcb0a62SAndroid Build Coastguard Worker   // Compressed length of this ZipEntry. The maximum value is UINT64_MAX.
127*adcb0a62SAndroid Build Coastguard Worker   // Might be present either in the local file header, the zip64 extended field,
128*adcb0a62SAndroid Build Coastguard Worker   // or in the data descriptor footer.
129*adcb0a62SAndroid Build Coastguard Worker   uint64_t compressed_length{0};
130*adcb0a62SAndroid Build Coastguard Worker 
131*adcb0a62SAndroid Build Coastguard Worker   // Uncompressed length of this ZipEntry. The maximum value is UINT64_MAX.
132*adcb0a62SAndroid Build Coastguard Worker   // Might be present either in the local file header, the zip64 extended field,
133*adcb0a62SAndroid Build Coastguard Worker   // or in the data descriptor footer.
134*adcb0a62SAndroid Build Coastguard Worker   uint64_t uncompressed_length{0};
135*adcb0a62SAndroid Build Coastguard Worker 
136*adcb0a62SAndroid Build Coastguard Worker   explicit ZipEntry64() = default;
ZipEntry64ZipEntry64137*adcb0a62SAndroid Build Coastguard Worker   explicit ZipEntry64(const ZipEntry& zip_entry) : ZipEntryCommon(zip_entry) {
138*adcb0a62SAndroid Build Coastguard Worker     compressed_length = zip_entry.compressed_length;
139*adcb0a62SAndroid Build Coastguard Worker     uncompressed_length = zip_entry.uncompressed_length;
140*adcb0a62SAndroid Build Coastguard Worker   }
141*adcb0a62SAndroid Build Coastguard Worker };
142*adcb0a62SAndroid Build Coastguard Worker 
143*adcb0a62SAndroid Build Coastguard Worker struct ZipArchive;
144*adcb0a62SAndroid Build Coastguard Worker typedef ZipArchive* ZipArchiveHandle;
145*adcb0a62SAndroid Build Coastguard Worker 
146*adcb0a62SAndroid Build Coastguard Worker /*
147*adcb0a62SAndroid Build Coastguard Worker  * Open a Zip archive, and sets handle to the value of the opaque
148*adcb0a62SAndroid Build Coastguard Worker  * handle for the file. This handle must be released by calling
149*adcb0a62SAndroid Build Coastguard Worker  * CloseArchive with this handle.
150*adcb0a62SAndroid Build Coastguard Worker  *
151*adcb0a62SAndroid Build Coastguard Worker  * Returns 0 on success, and negative values on failure.
152*adcb0a62SAndroid Build Coastguard Worker  */
153*adcb0a62SAndroid Build Coastguard Worker int32_t OpenArchive(const char* fileName, ZipArchiveHandle* handle);
154*adcb0a62SAndroid Build Coastguard Worker 
155*adcb0a62SAndroid Build Coastguard Worker /*
156*adcb0a62SAndroid Build Coastguard Worker  * Like OpenArchive, but takes a file descriptor open for reading
157*adcb0a62SAndroid Build Coastguard Worker  * at the start of the file.  The descriptor must be mappable (this does
158*adcb0a62SAndroid Build Coastguard Worker  * not allow access to a stream).
159*adcb0a62SAndroid Build Coastguard Worker  *
160*adcb0a62SAndroid Build Coastguard Worker  * Sets handle to the value of the opaque handle for this file descriptor.
161*adcb0a62SAndroid Build Coastguard Worker  * This handle must be released by calling CloseArchive with this handle.
162*adcb0a62SAndroid Build Coastguard Worker  *
163*adcb0a62SAndroid Build Coastguard Worker  * If assume_ownership parameter is 'true' calling CloseArchive will close
164*adcb0a62SAndroid Build Coastguard Worker  * the file.
165*adcb0a62SAndroid Build Coastguard Worker  *
166*adcb0a62SAndroid Build Coastguard Worker  * This function maps and scans the central directory and builds a table
167*adcb0a62SAndroid Build Coastguard Worker  * of entries for future lookups.
168*adcb0a62SAndroid Build Coastguard Worker  *
169*adcb0a62SAndroid Build Coastguard Worker  * "debugFileName" will appear in error messages, but is not otherwise used.
170*adcb0a62SAndroid Build Coastguard Worker  *
171*adcb0a62SAndroid Build Coastguard Worker  * Returns 0 on success, and negative values on failure.
172*adcb0a62SAndroid Build Coastguard Worker  */
173*adcb0a62SAndroid Build Coastguard Worker int32_t OpenArchiveFd(const int fd, const char* debugFileName, ZipArchiveHandle* handle,
174*adcb0a62SAndroid Build Coastguard Worker                       bool assume_ownership = true);
175*adcb0a62SAndroid Build Coastguard Worker 
176*adcb0a62SAndroid Build Coastguard Worker int32_t OpenArchiveFdRange(const int fd, const char* debugFileName, ZipArchiveHandle* handle,
177*adcb0a62SAndroid Build Coastguard Worker                            off64_t length, off64_t offset, bool assume_ownership = true);
178*adcb0a62SAndroid Build Coastguard Worker 
179*adcb0a62SAndroid Build Coastguard Worker int32_t OpenArchiveFromMemory(const void* address, size_t length, const char* debugFileName,
180*adcb0a62SAndroid Build Coastguard Worker                               ZipArchiveHandle* handle);
181*adcb0a62SAndroid Build Coastguard Worker /*
182*adcb0a62SAndroid Build Coastguard Worker  * Close archive, releasing resources associated with it. This will
183*adcb0a62SAndroid Build Coastguard Worker  * unmap the central directory of the zipfile and free all internal
184*adcb0a62SAndroid Build Coastguard Worker  * data structures associated with the file. It is an error to use
185*adcb0a62SAndroid Build Coastguard Worker  * this handle for any further operations without an intervening
186*adcb0a62SAndroid Build Coastguard Worker  * call to one of the OpenArchive variants.
187*adcb0a62SAndroid Build Coastguard Worker  */
188*adcb0a62SAndroid Build Coastguard Worker void CloseArchive(ZipArchiveHandle archive);
189*adcb0a62SAndroid Build Coastguard Worker 
190*adcb0a62SAndroid Build Coastguard Worker /** See GetArchiveInfo(). */
191*adcb0a62SAndroid Build Coastguard Worker struct ZipArchiveInfo {
192*adcb0a62SAndroid Build Coastguard Worker   /** The size in bytes of the archive itself. Used by zipinfo. */
193*adcb0a62SAndroid Build Coastguard Worker   off64_t archive_size;
194*adcb0a62SAndroid Build Coastguard Worker   /** The number of entries in the archive. */
195*adcb0a62SAndroid Build Coastguard Worker   uint64_t entry_count;
196*adcb0a62SAndroid Build Coastguard Worker };
197*adcb0a62SAndroid Build Coastguard Worker 
198*adcb0a62SAndroid Build Coastguard Worker /**
199*adcb0a62SAndroid Build Coastguard Worker  * Returns information about the given archive.
200*adcb0a62SAndroid Build Coastguard Worker  */
201*adcb0a62SAndroid Build Coastguard Worker ZipArchiveInfo GetArchiveInfo(ZipArchiveHandle archive);
202*adcb0a62SAndroid Build Coastguard Worker 
203*adcb0a62SAndroid Build Coastguard Worker /*
204*adcb0a62SAndroid Build Coastguard Worker  * Find an entry in the Zip archive, by name. |data| must be non-null.
205*adcb0a62SAndroid Build Coastguard Worker  *
206*adcb0a62SAndroid Build Coastguard Worker  * Returns 0 if an entry is found, and populates |data| with information
207*adcb0a62SAndroid Build Coastguard Worker  * about this entry. Returns negative values otherwise.
208*adcb0a62SAndroid Build Coastguard Worker  *
209*adcb0a62SAndroid Build Coastguard Worker  * It's important to note that |data->crc32|, |data->compLen| and
210*adcb0a62SAndroid Build Coastguard Worker  * |data->uncompLen| might be set to values from the central directory
211*adcb0a62SAndroid Build Coastguard Worker  * if this file entry contains a data descriptor footer. To verify crc32s
212*adcb0a62SAndroid Build Coastguard Worker  * and length, a call to VerifyCrcAndLengths must be made after entry data
213*adcb0a62SAndroid Build Coastguard Worker  * has been processed.
214*adcb0a62SAndroid Build Coastguard Worker  *
215*adcb0a62SAndroid Build Coastguard Worker  * On non-Windows platforms this method does not modify internal state and
216*adcb0a62SAndroid Build Coastguard Worker  * can be called concurrently.
217*adcb0a62SAndroid Build Coastguard Worker  */
218*adcb0a62SAndroid Build Coastguard Worker int32_t FindEntry(const ZipArchiveHandle archive, const std::string_view entryName,
219*adcb0a62SAndroid Build Coastguard Worker                   ZipEntry64* data);
220*adcb0a62SAndroid Build Coastguard Worker 
221*adcb0a62SAndroid Build Coastguard Worker /*
222*adcb0a62SAndroid Build Coastguard Worker  * Start iterating over all entries of a zip file. The order of iteration
223*adcb0a62SAndroid Build Coastguard Worker  * is not guaranteed to be the same as the order of elements
224*adcb0a62SAndroid Build Coastguard Worker  * in the central directory but is stable for a given zip file. |cookie| will
225*adcb0a62SAndroid Build Coastguard Worker  * contain the value of an opaque cookie which can be used to make one or more
226*adcb0a62SAndroid Build Coastguard Worker  * calls to Next. All calls to StartIteration must be matched by a call to
227*adcb0a62SAndroid Build Coastguard Worker  * EndIteration to free any allocated memory.
228*adcb0a62SAndroid Build Coastguard Worker  *
229*adcb0a62SAndroid Build Coastguard Worker  * This method also accepts optional prefix and suffix to restrict iteration to
230*adcb0a62SAndroid Build Coastguard Worker  * entry names that start with |optional_prefix| or end with |optional_suffix|.
231*adcb0a62SAndroid Build Coastguard Worker  *
232*adcb0a62SAndroid Build Coastguard Worker  * Returns 0 on success and negative values on failure.
233*adcb0a62SAndroid Build Coastguard Worker  */
234*adcb0a62SAndroid Build Coastguard Worker int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr,
235*adcb0a62SAndroid Build Coastguard Worker                        const std::string_view optional_prefix = "",
236*adcb0a62SAndroid Build Coastguard Worker                        const std::string_view optional_suffix = "");
237*adcb0a62SAndroid Build Coastguard Worker 
238*adcb0a62SAndroid Build Coastguard Worker /*
239*adcb0a62SAndroid Build Coastguard Worker  * Start iterating over all entries of a zip file. Use the matcher functor to
240*adcb0a62SAndroid Build Coastguard Worker  * restrict iteration to entry names that make the functor return true.
241*adcb0a62SAndroid Build Coastguard Worker  *
242*adcb0a62SAndroid Build Coastguard Worker  * Returns 0 on success and negative values on failure.
243*adcb0a62SAndroid Build Coastguard Worker  */
244*adcb0a62SAndroid Build Coastguard Worker int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr,
245*adcb0a62SAndroid Build Coastguard Worker                        std::function<bool(std::string_view entry_name)> matcher);
246*adcb0a62SAndroid Build Coastguard Worker 
247*adcb0a62SAndroid Build Coastguard Worker /*
248*adcb0a62SAndroid Build Coastguard Worker  * Advance to the next element in the zipfile in iteration order.
249*adcb0a62SAndroid Build Coastguard Worker  *
250*adcb0a62SAndroid Build Coastguard Worker  * Returns 0 on success, -1 if there are no more elements in this
251*adcb0a62SAndroid Build Coastguard Worker  * archive and lower negative values on failure.
252*adcb0a62SAndroid Build Coastguard Worker  */
253*adcb0a62SAndroid Build Coastguard Worker int32_t Next(void* cookie, ZipEntry64* data, std::string_view* name);
254*adcb0a62SAndroid Build Coastguard Worker int32_t Next(void* cookie, ZipEntry64* data, std::string* name);
255*adcb0a62SAndroid Build Coastguard Worker 
256*adcb0a62SAndroid Build Coastguard Worker /*
257*adcb0a62SAndroid Build Coastguard Worker  * End iteration over all entries of a zip file and frees the memory allocated
258*adcb0a62SAndroid Build Coastguard Worker  * in StartIteration.
259*adcb0a62SAndroid Build Coastguard Worker  */
260*adcb0a62SAndroid Build Coastguard Worker void EndIteration(void* cookie);
261*adcb0a62SAndroid Build Coastguard Worker 
262*adcb0a62SAndroid Build Coastguard Worker /*
263*adcb0a62SAndroid Build Coastguard Worker  * Uncompress and write an entry to an open file identified by |fd|.
264*adcb0a62SAndroid Build Coastguard Worker  * |entry->uncompressed_length| bytes will be written to the file at
265*adcb0a62SAndroid Build Coastguard Worker  * its current offset, and the file will be truncated at the end of
266*adcb0a62SAndroid Build Coastguard Worker  * the uncompressed data (no truncation if |fd| references a block
267*adcb0a62SAndroid Build Coastguard Worker  * device).
268*adcb0a62SAndroid Build Coastguard Worker  *
269*adcb0a62SAndroid Build Coastguard Worker  * Returns 0 on success and negative values on failure.
270*adcb0a62SAndroid Build Coastguard Worker  */
271*adcb0a62SAndroid Build Coastguard Worker int32_t ExtractEntryToFile(ZipArchiveHandle archive, const ZipEntry64* entry, int fd);
272*adcb0a62SAndroid Build Coastguard Worker 
273*adcb0a62SAndroid Build Coastguard Worker /**
274*adcb0a62SAndroid Build Coastguard Worker  * Uncompress a given zip entry to the memory region at |begin| and of
275*adcb0a62SAndroid Build Coastguard Worker  * size |size|. This size is expected to be the same as the *declared*
276*adcb0a62SAndroid Build Coastguard Worker  * uncompressed length of the zip entry. It is an error if the *actual*
277*adcb0a62SAndroid Build Coastguard Worker  * number of uncompressed bytes differs from this number.
278*adcb0a62SAndroid Build Coastguard Worker  *
279*adcb0a62SAndroid Build Coastguard Worker  * Returns 0 on success and negative values on failure.
280*adcb0a62SAndroid Build Coastguard Worker  */
281*adcb0a62SAndroid Build Coastguard Worker int32_t ExtractToMemory(ZipArchiveHandle archive, const ZipEntry64* entry, uint8_t* begin,
282*adcb0a62SAndroid Build Coastguard Worker                         size_t size);
283*adcb0a62SAndroid Build Coastguard Worker 
284*adcb0a62SAndroid Build Coastguard Worker int GetFileDescriptor(const ZipArchiveHandle archive);
285*adcb0a62SAndroid Build Coastguard Worker 
286*adcb0a62SAndroid Build Coastguard Worker /**
287*adcb0a62SAndroid Build Coastguard Worker  * Returns the offset of the zip archive in the backing file descriptor, or 0 if the zip archive is
288*adcb0a62SAndroid Build Coastguard Worker  * not backed by a file descriptor.
289*adcb0a62SAndroid Build Coastguard Worker  */
290*adcb0a62SAndroid Build Coastguard Worker off64_t GetFileDescriptorOffset(const ZipArchiveHandle archive);
291*adcb0a62SAndroid Build Coastguard Worker 
292*adcb0a62SAndroid Build Coastguard Worker const char* ErrorCodeString(int32_t error_code);
293*adcb0a62SAndroid Build Coastguard Worker 
294*adcb0a62SAndroid Build Coastguard Worker // Many users of libziparchive assume the entry size to be 32 bits long. So we keep these
295*adcb0a62SAndroid Build Coastguard Worker // interfaces that use 32 bit ZipEntry to make old code work. TODO(xunchang) Remove the 32 bit
296*adcb0a62SAndroid Build Coastguard Worker // wrapper functions once we switch all users to recognize ZipEntry64.
297*adcb0a62SAndroid Build Coastguard Worker int32_t FindEntry(const ZipArchiveHandle archive, const std::string_view entryName, ZipEntry* data);
298*adcb0a62SAndroid Build Coastguard Worker int32_t Next(void* cookie, ZipEntry* data, std::string* name);
299*adcb0a62SAndroid Build Coastguard Worker int32_t Next(void* cookie, ZipEntry* data, std::string_view* name);
300*adcb0a62SAndroid Build Coastguard Worker int32_t ExtractEntryToFile(ZipArchiveHandle archive, const ZipEntry* entry, int fd);
301*adcb0a62SAndroid Build Coastguard Worker int32_t ExtractToMemory(ZipArchiveHandle archive, const ZipEntry* entry, uint8_t* begin,
302*adcb0a62SAndroid Build Coastguard Worker                         size_t size);
303*adcb0a62SAndroid Build Coastguard Worker 
304*adcb0a62SAndroid Build Coastguard Worker //
305*adcb0a62SAndroid Build Coastguard Worker // This gets defined for the version of the library that need to control all
306*adcb0a62SAndroid Build Coastguard Worker // code accessing the zip file. Details in incfs_support/signal_handling.h
307*adcb0a62SAndroid Build Coastguard Worker //
308*adcb0a62SAndroid Build Coastguard Worker #if !ZIPARCHIVE_DISABLE_CALLBACK_API
309*adcb0a62SAndroid Build Coastguard Worker 
310*adcb0a62SAndroid Build Coastguard Worker #if !defined(_WIN32)
311*adcb0a62SAndroid Build Coastguard Worker typedef bool (*ProcessZipEntryFunction)(const uint8_t* buf, size_t buf_size, void* cookie);
312*adcb0a62SAndroid Build Coastguard Worker 
313*adcb0a62SAndroid Build Coastguard Worker /*
314*adcb0a62SAndroid Build Coastguard Worker  * Stream the uncompressed data through the supplied function,
315*adcb0a62SAndroid Build Coastguard Worker  * passing cookie to it each time it gets called.
316*adcb0a62SAndroid Build Coastguard Worker  */
317*adcb0a62SAndroid Build Coastguard Worker int32_t ProcessZipEntryContents(ZipArchiveHandle archive, const ZipEntry* entry,
318*adcb0a62SAndroid Build Coastguard Worker                                 ProcessZipEntryFunction func, void* cookie);
319*adcb0a62SAndroid Build Coastguard Worker int32_t ProcessZipEntryContents(ZipArchiveHandle archive, const ZipEntry64* entry,
320*adcb0a62SAndroid Build Coastguard Worker                                 ProcessZipEntryFunction func, void* cookie);
321*adcb0a62SAndroid Build Coastguard Worker #endif  // !defined(_WIN32)
322*adcb0a62SAndroid Build Coastguard Worker 
323*adcb0a62SAndroid Build Coastguard Worker #endif  // !ZIPARCHIVE_DISABLE_CALLBACK_API
324*adcb0a62SAndroid Build Coastguard Worker 
325*adcb0a62SAndroid Build Coastguard Worker namespace zip_archive {
326*adcb0a62SAndroid Build Coastguard Worker 
327*adcb0a62SAndroid Build Coastguard Worker class Writer {
328*adcb0a62SAndroid Build Coastguard Worker  public:
329*adcb0a62SAndroid Build Coastguard Worker   virtual bool Append(uint8_t* buf, size_t buf_size) = 0;
330*adcb0a62SAndroid Build Coastguard Worker 
331*adcb0a62SAndroid Build Coastguard Worker   // Returns the internal buffer that can we written into directly.
332*adcb0a62SAndroid Build Coastguard Worker   using Buffer = std::pair<uint8_t*, size_t>;
333*adcb0a62SAndroid Build Coastguard Worker   virtual Buffer GetBuffer(size_t length);
334*adcb0a62SAndroid Build Coastguard Worker 
335*adcb0a62SAndroid Build Coastguard Worker  protected:
336*adcb0a62SAndroid Build Coastguard Worker   Writer() = default;
337*adcb0a62SAndroid Build Coastguard Worker   ~Writer() = default;
338*adcb0a62SAndroid Build Coastguard Worker 
339*adcb0a62SAndroid Build Coastguard Worker  private:
340*adcb0a62SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(Writer);
341*adcb0a62SAndroid Build Coastguard Worker };
342*adcb0a62SAndroid Build Coastguard Worker 
343*adcb0a62SAndroid Build Coastguard Worker class LowLevelReader {
344*adcb0a62SAndroid Build Coastguard Worker  public:
345*adcb0a62SAndroid Build Coastguard Worker   // Get |len| bytes of data starting at |offset|, either by copying them into the supplied |buf|,
346*adcb0a62SAndroid Build Coastguard Worker   // or returning an internal buffer directly.
347*adcb0a62SAndroid Build Coastguard Worker   // Returns a pointer to the data (which can be different from |buf|), or |nullptr| on error.
348*adcb0a62SAndroid Build Coastguard Worker   virtual const uint8_t* AccessAtOffset(uint8_t* buf, size_t len, off64_t offset) const = 0;
349*adcb0a62SAndroid Build Coastguard Worker 
350*adcb0a62SAndroid Build Coastguard Worker   // Returns |true| if the reader doesn't need an external buffer but instead returns its own one.
351*adcb0a62SAndroid Build Coastguard Worker   virtual bool IsZeroCopy() const = 0;
352*adcb0a62SAndroid Build Coastguard Worker 
353*adcb0a62SAndroid Build Coastguard Worker  protected:
354*adcb0a62SAndroid Build Coastguard Worker   LowLevelReader() = default;
355*adcb0a62SAndroid Build Coastguard Worker   ~LowLevelReader() = default;
356*adcb0a62SAndroid Build Coastguard Worker 
357*adcb0a62SAndroid Build Coastguard Worker  private:
358*adcb0a62SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(LowLevelReader);
359*adcb0a62SAndroid Build Coastguard Worker };
360*adcb0a62SAndroid Build Coastguard Worker 
361*adcb0a62SAndroid Build Coastguard Worker class Reader : public LowLevelReader {
362*adcb0a62SAndroid Build Coastguard Worker  public:
363*adcb0a62SAndroid Build Coastguard Worker   virtual bool ReadAtOffset(uint8_t* buf, size_t len, off64_t offset) const = 0;
364*adcb0a62SAndroid Build Coastguard Worker 
365*adcb0a62SAndroid Build Coastguard Worker   // Ensure the existing classes implementing Reader don't need to bother with
366*adcb0a62SAndroid Build Coastguard Worker   // the new method.
367*adcb0a62SAndroid Build Coastguard Worker   const uint8_t* AccessAtOffset(uint8_t* buf, size_t len, off64_t offset) const override;
368*adcb0a62SAndroid Build Coastguard Worker   bool IsZeroCopy() const override;
369*adcb0a62SAndroid Build Coastguard Worker 
370*adcb0a62SAndroid Build Coastguard Worker  protected:
371*adcb0a62SAndroid Build Coastguard Worker   Reader() = default;
372*adcb0a62SAndroid Build Coastguard Worker   ~Reader() = default;
373*adcb0a62SAndroid Build Coastguard Worker 
374*adcb0a62SAndroid Build Coastguard Worker  private:
375*adcb0a62SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(Reader);
376*adcb0a62SAndroid Build Coastguard Worker };
377*adcb0a62SAndroid Build Coastguard Worker 
378*adcb0a62SAndroid Build Coastguard Worker //
379*adcb0a62SAndroid Build Coastguard Worker // This gets defined for the version of the library that need to control all
380*adcb0a62SAndroid Build Coastguard Worker // code accessing the zip file. Details in incfs_support/signal_handling.h
381*adcb0a62SAndroid Build Coastguard Worker //
382*adcb0a62SAndroid Build Coastguard Worker #if !ZIPARCHIVE_DISABLE_CALLBACK_API
383*adcb0a62SAndroid Build Coastguard Worker 
384*adcb0a62SAndroid Build Coastguard Worker /**
385*adcb0a62SAndroid Build Coastguard Worker  * Uncompress a given zip entry to given |writer|.
386*adcb0a62SAndroid Build Coastguard Worker  *
387*adcb0a62SAndroid Build Coastguard Worker  * Returns 0 on success and negative values on failure.
388*adcb0a62SAndroid Build Coastguard Worker  */
389*adcb0a62SAndroid Build Coastguard Worker int32_t ExtractToWriter(ZipArchiveHandle handle, const ZipEntry64* entry,
390*adcb0a62SAndroid Build Coastguard Worker                         zip_archive::Writer* writer);
391*adcb0a62SAndroid Build Coastguard Worker 
392*adcb0a62SAndroid Build Coastguard Worker #endif  // !ZIPARCHIVE_DISABLE_CALLBACK_API
393*adcb0a62SAndroid Build Coastguard Worker 
394*adcb0a62SAndroid Build Coastguard Worker /*
395*adcb0a62SAndroid Build Coastguard Worker  * Inflates the first |compressed_length| bytes of |reader| to a given |writer|.
396*adcb0a62SAndroid Build Coastguard Worker  * |crc_out| is set to the CRC32 checksum of the uncompressed data.
397*adcb0a62SAndroid Build Coastguard Worker  *
398*adcb0a62SAndroid Build Coastguard Worker  * Returns 0 on success and negative values on failure, for example if |reader|
399*adcb0a62SAndroid Build Coastguard Worker  * cannot supply the right amount of data, or if the number of bytes written to
400*adcb0a62SAndroid Build Coastguard Worker  * data does not match |uncompressed_length|.
401*adcb0a62SAndroid Build Coastguard Worker  *
402*adcb0a62SAndroid Build Coastguard Worker  * If |crc_out| is not nullptr, it is set to the crc32 checksum of the
403*adcb0a62SAndroid Build Coastguard Worker  * uncompressed data.
404*adcb0a62SAndroid Build Coastguard Worker  *
405*adcb0a62SAndroid Build Coastguard Worker  * NOTE: in the IncFS version of the library this function remains
406*adcb0a62SAndroid Build Coastguard Worker  * unprotected, because the data |reader| is supplying is under the full reader's
407*adcb0a62SAndroid Build Coastguard Worker  * control; it's the reader's duty to ensure it is available and OK to access.
408*adcb0a62SAndroid Build Coastguard Worker  */
409*adcb0a62SAndroid Build Coastguard Worker int32_t Inflate(const Reader& reader, const uint64_t compressed_length,
410*adcb0a62SAndroid Build Coastguard Worker                 const uint64_t uncompressed_length, Writer* writer, uint64_t* crc_out);
411*adcb0a62SAndroid Build Coastguard Worker 
412*adcb0a62SAndroid Build Coastguard Worker }  // namespace zip_archive
413