1/**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBZIPARCHIVE_ZIP_ARCHIVE_H
17#define LIBZIPARCHIVE_ZIP_ARCHIVE_H
18
19#include <cstdint>
20#include <contrib/minizip/unzip.h>
21#include <contrib/minizip/zip.h>
22
23namespace panda {
24
25constexpr int ZIPARCHIVE_OK = 0;
26constexpr int ZIPARCHIVE_ERR = 1;
27
28using ZipArchiveHandle = unzFile;
29
30struct EntryFileStat {
31public:
32    uint32_t GetUncompressedSize() const
33    {
34        return static_cast<uint32_t>(file_stat.uncompressed_size);
35    }
36
37    uint32_t GetCompressedSize() const
38    {
39        return static_cast<uint32_t>(file_stat.compressed_size);
40    }
41
42    inline uint32_t GetOffset() const
43    {
44        return offset;
45    }
46
47    inline bool IsCompressed() const
48    {
49        return file_stat.compression_method != 0;
50    }
51
52    unz_file_info file_stat;
53    uint32_t offset;
54};
55
56struct GlobalStat {
57public:
58    uint32_t GetNumberOfEntry() const
59    {
60        return static_cast<uint32_t>(ginfo.number_entry);
61    }
62    unz_global_info ginfo;
63};
64
65/*
66 * Judge whether magic is zip magic.
67 */
68bool IsZipMagic(uint32_t magic);
69
70/*
71 * Open a Zip archive from filename path, and sets handle for the file.
72 * This handle must be released by calling CloseArchive with this handle.
73 * CloseArchive will close the file opened.
74 *
75 * Returns 0 on success, and 1 on failure.
76 */
77int OpenArchive(ZipArchiveHandle &handle, const char *path);
78
79/*
80 * Close archive opened with OpenArchive, releasing internal resources associated with it.
81 */
82int CloseArchive(ZipArchiveHandle &handle);
83
84/*
85 * Open a Zip archive from opened file FILE* fp, and sets handle for the file.
86 * This handle must be released by calling CloseArchiveFile with this handle.
87 * CloseArchiveFile will not close the fp. It is the caller's responsibility.
88 *
89 * Returns 0 on success, and 1 on failure.
90 */
91int OpenArchiveFile(ZipArchiveHandle &handle, FILE *fp);
92
93/*
94 * Close archive opened with OpenArchiveFile, releasing internal resources associated with it.
95 *
96 * Returns 0 on success, and 1 on failure.
97 */
98int CloseArchiveFile(ZipArchiveHandle &handle);
99
100/*
101 * Write info about the ZipFile in the *gstat structure.
102 * No preparation of the structure is needed
103 *
104 * Returns 0 on success, and 1 on failure.
105 */
106int GetGlobalFileInfo(ZipArchiveHandle &handle, GlobalStat *gstat);
107
108/*
109 * Set the current file of the zipfile to the next file.
110 *
111 * Returns 0 on success, and 1 on failure.
112 */
113int GoToNextFile(ZipArchiveHandle &handle);
114
115/*
116 * Try locate the file filename in the zipfile.
117 *
118 * Returns 0 on success, and 1 on failure.
119 */
120int LocateFile(ZipArchiveHandle &handle, const char *filename);
121
122/*
123 * Get Info about the current file within ZipFile and write info into the *entry structure.
124 * No preparation of the structure is needed
125 *
126 * Returns 0 on success, and 1 on failure.
127 */
128int GetCurrentFileInfo(ZipArchiveHandle &handle, EntryFileStat *entry);
129
130/*
131 * Open for reading data the current file in the zipfile.
132 * This handle must be released by calling CloseCurrentFile with this handle.
133 *
134 * Returns 0 on success, and 1 on failure.
135 */
136int OpenCurrentFile(ZipArchiveHandle &handle);
137
138/*
139 * Get the current file offset opened with OpenCurrentFile. The offset will be stored into entry->offset.
140 */
141void GetCurrentFileOffset(ZipArchiveHandle &handle, EntryFileStat *entry);
142
143/*
144 * Close the file in zip opened with unzOpenCurrentFile
145 *
146 * Returns 0 on success, and 1 on failure.
147 */
148int CloseCurrentFile(ZipArchiveHandle &handle);
149
150/*
151 * Uncompress a given zip archive represented with handle to buf of size |buf_size|.
152 * This size is expected to be equal or larger than the uncompressed length of the zip entry.
153 *
154 * Returns 0 on success and 1 on failure.
155 */
156int ExtractToMemory(ZipArchiveHandle &handle, void *buf, size_t buf_size);
157
158/*
159 * Add a new file filename(resident in memory pbuf which has size of size |buf_size|) to the archive zipname,
160 * append takes value from APPEND_STATUS_CREATE(which will create the archive zipname for first time) and
161 * APPEND_STATUS_ADDINZIP(which will append filename into exsisted zip archive zipname).
162 * level takes value from Z_BEST_COMPRESSION(which will deflate the pbuf with best compression effect) and
163 * Z_NO_COMPRESSION(which will store the pbuf into zipname without compression).
164 *
165 * Returns 0 on success and 1 on failure.
166 */
167int CreateOrAddFileIntoZip(const char *zipname, const char *filename, const void *pbuf, size_t buf_size,
168                           int append = APPEND_STATUS_CREATE, int level = Z_BEST_COMPRESSION);
169}  // namespace panda
170
171#endif  // LIBZIPARCHIVE_ZIP_ARCHIVE_H
172