Home | History | Annotate | Download | only in ziparchive
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*
     18  * Read-only access to Zip archives, with minimal heap allocation.
     19  */
     20 #ifndef LIBZIPARCHIVE_ZIPARCHIVE_H_
     21 #define LIBZIPARCHIVE_ZIPARCHIVE_H_
     22 
     23 #include <stdint.h>
     24 #include <string.h>
     25 #include <sys/types.h>
     26 #include <utils/Compat.h>
     27 
     28 __BEGIN_DECLS
     29 
     30 /* Zip compression methods we support */
     31 enum {
     32   kCompressStored     = 0,        // no compression
     33   kCompressDeflated   = 8,        // standard deflate
     34 };
     35 
     36 struct ZipEntryName {
     37   const uint8_t* name;
     38   uint16_t name_length;
     39 
     40   ZipEntryName() {}
     41 
     42   /*
     43    * entry_name has to be an c-style string with only ASCII characters.
     44    */
     45   explicit ZipEntryName(const char* entry_name)
     46       : name(reinterpret_cast<const uint8_t*>(entry_name)), name_length(strlen(entry_name)) {}
     47 };
     48 
     49 /*
     50  * Represents information about a zip entry in a zip file.
     51  */
     52 struct ZipEntry {
     53   // Compression method: One of kCompressStored or
     54   // kCompressDeflated.
     55   uint16_t method;
     56 
     57   // Modification time. The zipfile format specifies
     58   // that the first two little endian bytes contain the time
     59   // and the last two little endian bytes contain the date.
     60   uint32_t mod_time;
     61 
     62   // 1 if this entry contains a data descriptor segment, 0
     63   // otherwise.
     64   uint8_t has_data_descriptor;
     65 
     66   // Crc32 value of this ZipEntry. This information might
     67   // either be stored in the local file header or in a special
     68   // Data descriptor footer at the end of the file entry.
     69   uint32_t crc32;
     70 
     71   // Compressed length of this ZipEntry. Might be present
     72   // either in the local file header or in the data descriptor
     73   // footer.
     74   uint32_t compressed_length;
     75 
     76   // Uncompressed length of this ZipEntry. Might be present
     77   // either in the local file header or in the data descriptor
     78   // footer.
     79   uint32_t uncompressed_length;
     80 
     81   // The offset to the start of data for this ZipEntry.
     82   off64_t offset;
     83 };
     84 
     85 typedef void* ZipArchiveHandle;
     86 
     87 /*
     88  * Open a Zip archive, and sets handle to the value of the opaque
     89  * handle for the file. This handle must be released by calling
     90  * CloseArchive with this handle.
     91  *
     92  * Returns 0 on success, and negative values on failure.
     93  */
     94 int32_t OpenArchive(const char* fileName, ZipArchiveHandle* handle);
     95 
     96 /*
     97  * Like OpenArchive, but takes a file descriptor open for reading
     98  * at the start of the file.  The descriptor must be mappable (this does
     99  * not allow access to a stream).
    100  *
    101  * Sets handle to the value of the opaque handle for this file descriptor.
    102  * This handle must be released by calling CloseArchive with this handle.
    103  *
    104  * If assume_ownership parameter is 'true' calling CloseArchive will close
    105  * the file.
    106  *
    107  * This function maps and scans the central directory and builds a table
    108  * of entries for future lookups.
    109  *
    110  * "debugFileName" will appear in error messages, but is not otherwise used.
    111  *
    112  * Returns 0 on success, and negative values on failure.
    113  */
    114 int32_t OpenArchiveFd(const int fd, const char* debugFileName,
    115                       ZipArchiveHandle *handle, bool assume_ownership = true);
    116 
    117 /*
    118  * Close archive, releasing resources associated with it. This will
    119  * unmap the central directory of the zipfile and free all internal
    120  * data structures associated with the file. It is an error to use
    121  * this handle for any further operations without an intervening
    122  * call to one of the OpenArchive variants.
    123  */
    124 void CloseArchive(ZipArchiveHandle handle);
    125 
    126 /*
    127  * Find an entry in the Zip archive, by name. |entryName| must be a null
    128  * terminated string, and |data| must point to a writeable memory location.
    129  *
    130  * Returns 0 if an entry is found, and populates |data| with information
    131  * about this entry. Returns negative values otherwise.
    132  *
    133  * It's important to note that |data->crc32|, |data->compLen| and
    134  * |data->uncompLen| might be set to values from the central directory
    135  * if this file entry contains a data descriptor footer. To verify crc32s
    136  * and length, a call to VerifyCrcAndLengths must be made after entry data
    137  * has been processed.
    138  */
    139 int32_t FindEntry(const ZipArchiveHandle handle, const ZipEntryName& entryName,
    140                   ZipEntry* data);
    141 
    142 /*
    143  * Start iterating over all entries of a zip file. The order of iteration
    144  * is not guaranteed to be the same as the order of elements
    145  * in the central directory but is stable for a given zip file. |cookie| will
    146  * contain the value of an opaque cookie which can be used to make one or more
    147  * calls to Next. All calls to StartIteration must be matched by a call to
    148  * EndIteration to free any allocated memory.
    149  *
    150  * This method also accepts an optional prefix to restrict iteration to
    151  * entry names that start with |optional_prefix|.
    152  *
    153  * Returns 0 on success and negative values on failure.
    154  */
    155 int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr,
    156                        const ZipEntryName* optional_prefix,
    157                        // TODO: Remove the default parameter.
    158                        const ZipEntryName* optional_suffix = NULL);
    159 
    160 /*
    161  * Advance to the next element in the zipfile in iteration order.
    162  *
    163  * Returns 0 on success, -1 if there are no more elements in this
    164  * archive and lower negative values on failure.
    165  */
    166 int32_t Next(void* cookie, ZipEntry* data, ZipEntryName *name);
    167 
    168 /*
    169  * End iteration over all entries of a zip file and frees the memory allocated
    170  * in StartIteration.
    171  */
    172 void EndIteration(void* cookie);
    173 
    174 /*
    175  * Uncompress and write an entry to an open file identified by |fd|.
    176  * |entry->uncompressed_length| bytes will be written to the file at
    177  * its current offset, and the file will be truncated at the end of
    178  * the uncompressed data.
    179  *
    180  * Returns 0 on success and negative values on failure.
    181  */
    182 int32_t ExtractEntryToFile(ZipArchiveHandle handle, ZipEntry* entry, int fd);
    183 
    184 /**
    185  * Uncompress a given zip entry to the memory region at |begin| and of
    186  * size |size|. This size is expected to be the same as the *declared*
    187  * uncompressed length of the zip entry. It is an error if the *actual*
    188  * number of uncompressed bytes differs from this number.
    189  *
    190  * Returns 0 on success and negative values on failure.
    191  */
    192 int32_t ExtractToMemory(ZipArchiveHandle handle, ZipEntry* entry,
    193                         uint8_t* begin, uint32_t size);
    194 
    195 int GetFileDescriptor(const ZipArchiveHandle handle);
    196 
    197 const char* ErrorCodeString(int32_t error_code);
    198 
    199 __END_DECLS
    200 
    201 #endif  // LIBZIPARCHIVE_ZIPARCHIVE_H_
    202