xref: /aosp_15_r20/frameworks/base/libs/androidfw/ZipFileRO.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2007 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker //
18*d57664e9SAndroid Build Coastguard Worker // Read-only access to Zip archives, with minimal heap allocation.
19*d57664e9SAndroid Build Coastguard Worker //
20*d57664e9SAndroid Build Coastguard Worker #define LOG_TAG "zipro"
21*d57664e9SAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
22*d57664e9SAndroid Build Coastguard Worker #include <androidfw/ZipFileRO.h>
23*d57664e9SAndroid Build Coastguard Worker #include <utils/Log.h>
24*d57664e9SAndroid Build Coastguard Worker #include <utils/Compat.h>
25*d57664e9SAndroid Build Coastguard Worker #include <utils/misc.h>
26*d57664e9SAndroid Build Coastguard Worker #include <utils/threads.h>
27*d57664e9SAndroid Build Coastguard Worker #include <ziparchive/zip_archive.h>
28*d57664e9SAndroid Build Coastguard Worker 
29*d57664e9SAndroid Build Coastguard Worker #include <zlib.h>
30*d57664e9SAndroid Build Coastguard Worker 
31*d57664e9SAndroid Build Coastguard Worker #include <string.h>
32*d57664e9SAndroid Build Coastguard Worker #include <fcntl.h>
33*d57664e9SAndroid Build Coastguard Worker #include <errno.h>
34*d57664e9SAndroid Build Coastguard Worker #include <assert.h>
35*d57664e9SAndroid Build Coastguard Worker #include <unistd.h>
36*d57664e9SAndroid Build Coastguard Worker 
37*d57664e9SAndroid Build Coastguard Worker using namespace android;
38*d57664e9SAndroid Build Coastguard Worker 
39*d57664e9SAndroid Build Coastguard Worker class _ZipEntryRO {
40*d57664e9SAndroid Build Coastguard Worker public:
41*d57664e9SAndroid Build Coastguard Worker     ZipEntry entry;
42*d57664e9SAndroid Build Coastguard Worker     std::string_view name;
43*d57664e9SAndroid Build Coastguard Worker     void *cookie = nullptr;
44*d57664e9SAndroid Build Coastguard Worker 
45*d57664e9SAndroid Build Coastguard Worker     _ZipEntryRO() = default;
46*d57664e9SAndroid Build Coastguard Worker 
~_ZipEntryRO()47*d57664e9SAndroid Build Coastguard Worker     ~_ZipEntryRO() {
48*d57664e9SAndroid Build Coastguard Worker         EndIteration(cookie);
49*d57664e9SAndroid Build Coastguard Worker     }
50*d57664e9SAndroid Build Coastguard Worker 
convertToPtr()51*d57664e9SAndroid Build Coastguard Worker     android::ZipEntryRO convertToPtr() {
52*d57664e9SAndroid Build Coastguard Worker         _ZipEntryRO* result = new _ZipEntryRO;
53*d57664e9SAndroid Build Coastguard Worker         result->entry = std::move(this->entry);
54*d57664e9SAndroid Build Coastguard Worker         result->name = std::move(this->name);
55*d57664e9SAndroid Build Coastguard Worker         result->cookie = std::exchange(this->cookie, nullptr);
56*d57664e9SAndroid Build Coastguard Worker         return result;
57*d57664e9SAndroid Build Coastguard Worker     }
58*d57664e9SAndroid Build Coastguard Worker 
59*d57664e9SAndroid Build Coastguard Worker private:
60*d57664e9SAndroid Build Coastguard Worker     DISALLOW_COPY_AND_ASSIGN(_ZipEntryRO);
61*d57664e9SAndroid Build Coastguard Worker };
62*d57664e9SAndroid Build Coastguard Worker 
~ZipFileRO()63*d57664e9SAndroid Build Coastguard Worker ZipFileRO::~ZipFileRO() {
64*d57664e9SAndroid Build Coastguard Worker     CloseArchive(mHandle);
65*d57664e9SAndroid Build Coastguard Worker     if (mFileName != NULL) {
66*d57664e9SAndroid Build Coastguard Worker         free(mFileName);
67*d57664e9SAndroid Build Coastguard Worker     }
68*d57664e9SAndroid Build Coastguard Worker }
69*d57664e9SAndroid Build Coastguard Worker 
70*d57664e9SAndroid Build Coastguard Worker /*
71*d57664e9SAndroid Build Coastguard Worker  * Open the specified file read-only.  We memory-map the entire thing and
72*d57664e9SAndroid Build Coastguard Worker  * close the file before returning.
73*d57664e9SAndroid Build Coastguard Worker  */
open(const char * zipFileName)74*d57664e9SAndroid Build Coastguard Worker /* static */ ZipFileRO* ZipFileRO::open(const char* zipFileName)
75*d57664e9SAndroid Build Coastguard Worker {
76*d57664e9SAndroid Build Coastguard Worker     ZipArchiveHandle handle;
77*d57664e9SAndroid Build Coastguard Worker     const int32_t error = OpenArchive(zipFileName, &handle);
78*d57664e9SAndroid Build Coastguard Worker     if (error) {
79*d57664e9SAndroid Build Coastguard Worker         ALOGW("Error opening archive %s: %s", zipFileName, ErrorCodeString(error));
80*d57664e9SAndroid Build Coastguard Worker         CloseArchive(handle);
81*d57664e9SAndroid Build Coastguard Worker         return NULL;
82*d57664e9SAndroid Build Coastguard Worker     }
83*d57664e9SAndroid Build Coastguard Worker 
84*d57664e9SAndroid Build Coastguard Worker     return new ZipFileRO(handle, strdup(zipFileName));
85*d57664e9SAndroid Build Coastguard Worker }
86*d57664e9SAndroid Build Coastguard Worker 
87*d57664e9SAndroid Build Coastguard Worker 
openFd(int fd,const char * debugFileName,bool assume_ownership)88*d57664e9SAndroid Build Coastguard Worker /* static */ ZipFileRO* ZipFileRO::openFd(int fd, const char* debugFileName,
89*d57664e9SAndroid Build Coastguard Worker         bool assume_ownership)
90*d57664e9SAndroid Build Coastguard Worker {
91*d57664e9SAndroid Build Coastguard Worker     ZipArchiveHandle handle;
92*d57664e9SAndroid Build Coastguard Worker     const int32_t error = OpenArchiveFd(fd, debugFileName, &handle, assume_ownership);
93*d57664e9SAndroid Build Coastguard Worker     if (error) {
94*d57664e9SAndroid Build Coastguard Worker         ALOGW("Error opening archive fd %d %s: %s", fd, debugFileName, ErrorCodeString(error));
95*d57664e9SAndroid Build Coastguard Worker         CloseArchive(handle);
96*d57664e9SAndroid Build Coastguard Worker         return NULL;
97*d57664e9SAndroid Build Coastguard Worker     }
98*d57664e9SAndroid Build Coastguard Worker 
99*d57664e9SAndroid Build Coastguard Worker     return new ZipFileRO(handle, strdup(debugFileName));
100*d57664e9SAndroid Build Coastguard Worker }
101*d57664e9SAndroid Build Coastguard Worker 
findEntryByName(const char * entryName) const102*d57664e9SAndroid Build Coastguard Worker ZipEntryRO ZipFileRO::findEntryByName(const char* entryName) const
103*d57664e9SAndroid Build Coastguard Worker {
104*d57664e9SAndroid Build Coastguard Worker     _ZipEntryRO data;
105*d57664e9SAndroid Build Coastguard Worker     data.name = entryName;
106*d57664e9SAndroid Build Coastguard Worker 
107*d57664e9SAndroid Build Coastguard Worker     const int32_t error = FindEntry(mHandle, entryName, &(data.entry));
108*d57664e9SAndroid Build Coastguard Worker     if (error) {
109*d57664e9SAndroid Build Coastguard Worker         return nullptr;
110*d57664e9SAndroid Build Coastguard Worker     }
111*d57664e9SAndroid Build Coastguard Worker 
112*d57664e9SAndroid Build Coastguard Worker     return data.convertToPtr();
113*d57664e9SAndroid Build Coastguard Worker }
114*d57664e9SAndroid Build Coastguard Worker 
115*d57664e9SAndroid Build Coastguard Worker /*
116*d57664e9SAndroid Build Coastguard Worker  * Get the useful fields from the zip entry.
117*d57664e9SAndroid Build Coastguard Worker  *
118*d57664e9SAndroid Build Coastguard Worker  * Returns "false" if the offsets to the fields or the contents of the fields
119*d57664e9SAndroid Build Coastguard Worker  * appear to be bogus.
120*d57664e9SAndroid Build Coastguard Worker  */
getEntryInfo(ZipEntryRO entry,uint16_t * pMethod,uint32_t * pUncompLen,uint32_t * pCompLen,off64_t * pOffset,uint32_t * pModWhen,uint32_t * pCrc32,uint16_t * pExtraFieldSize) const121*d57664e9SAndroid Build Coastguard Worker bool ZipFileRO::getEntryInfo(ZipEntryRO entry, uint16_t* pMethod,
122*d57664e9SAndroid Build Coastguard Worker     uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset,
123*d57664e9SAndroid Build Coastguard Worker     uint32_t* pModWhen, uint32_t* pCrc32, uint16_t* pExtraFieldSize) const
124*d57664e9SAndroid Build Coastguard Worker {
125*d57664e9SAndroid Build Coastguard Worker     const _ZipEntryRO* zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);
126*d57664e9SAndroid Build Coastguard Worker     const ZipEntry& ze = zipEntry->entry;
127*d57664e9SAndroid Build Coastguard Worker 
128*d57664e9SAndroid Build Coastguard Worker     if (pMethod != nullptr) {
129*d57664e9SAndroid Build Coastguard Worker         *pMethod = ze.method;
130*d57664e9SAndroid Build Coastguard Worker     }
131*d57664e9SAndroid Build Coastguard Worker     if (pUncompLen != nullptr) {
132*d57664e9SAndroid Build Coastguard Worker         *pUncompLen = ze.uncompressed_length;
133*d57664e9SAndroid Build Coastguard Worker     }
134*d57664e9SAndroid Build Coastguard Worker     if (pCompLen != nullptr) {
135*d57664e9SAndroid Build Coastguard Worker         *pCompLen = ze.compressed_length;
136*d57664e9SAndroid Build Coastguard Worker     }
137*d57664e9SAndroid Build Coastguard Worker     if (pOffset != nullptr) {
138*d57664e9SAndroid Build Coastguard Worker         *pOffset = ze.offset;
139*d57664e9SAndroid Build Coastguard Worker     }
140*d57664e9SAndroid Build Coastguard Worker     if (pModWhen != nullptr) {
141*d57664e9SAndroid Build Coastguard Worker         *pModWhen = ze.mod_time;
142*d57664e9SAndroid Build Coastguard Worker     }
143*d57664e9SAndroid Build Coastguard Worker     if (pCrc32 != nullptr) {
144*d57664e9SAndroid Build Coastguard Worker         *pCrc32 = ze.crc32;
145*d57664e9SAndroid Build Coastguard Worker     }
146*d57664e9SAndroid Build Coastguard Worker     if (pExtraFieldSize != nullptr) {
147*d57664e9SAndroid Build Coastguard Worker         *pExtraFieldSize = ze.extra_field_size;
148*d57664e9SAndroid Build Coastguard Worker     }
149*d57664e9SAndroid Build Coastguard Worker 
150*d57664e9SAndroid Build Coastguard Worker     return true;
151*d57664e9SAndroid Build Coastguard Worker }
152*d57664e9SAndroid Build Coastguard Worker 
startIteration(void ** cookie)153*d57664e9SAndroid Build Coastguard Worker bool ZipFileRO::startIteration(void** cookie) {
154*d57664e9SAndroid Build Coastguard Worker   return startIteration(cookie, nullptr, nullptr);
155*d57664e9SAndroid Build Coastguard Worker }
156*d57664e9SAndroid Build Coastguard Worker 
startIteration(void ** cookie,const char * prefix,const char * suffix)157*d57664e9SAndroid Build Coastguard Worker bool ZipFileRO::startIteration(void** cookie, const char* prefix, const char* suffix) {
158*d57664e9SAndroid Build Coastguard Worker     auto result = startIterationOrError(prefix, suffix);
159*d57664e9SAndroid Build Coastguard Worker     if (!result.ok()) {
160*d57664e9SAndroid Build Coastguard Worker         return false;
161*d57664e9SAndroid Build Coastguard Worker     }
162*d57664e9SAndroid Build Coastguard Worker     *cookie = result.value();
163*d57664e9SAndroid Build Coastguard Worker     return true;
164*d57664e9SAndroid Build Coastguard Worker }
165*d57664e9SAndroid Build Coastguard Worker 
166*d57664e9SAndroid Build Coastguard Worker base::expected<void*, int32_t>
startIterationOrError(const char * prefix,const char * suffix)167*d57664e9SAndroid Build Coastguard Worker ZipFileRO::startIterationOrError(const char* prefix, const char* suffix) {
168*d57664e9SAndroid Build Coastguard Worker     _ZipEntryRO ze;
169*d57664e9SAndroid Build Coastguard Worker     int32_t error = StartIteration(mHandle, &(ze.cookie),
170*d57664e9SAndroid Build Coastguard Worker                                    prefix ? prefix : "", suffix ? suffix : "");
171*d57664e9SAndroid Build Coastguard Worker     if (error) {
172*d57664e9SAndroid Build Coastguard Worker         ALOGW("Could not start iteration over %s: %s", mFileName != NULL ? mFileName : "<null>",
173*d57664e9SAndroid Build Coastguard Worker                 ErrorCodeString(error));
174*d57664e9SAndroid Build Coastguard Worker         return base::unexpected(error);
175*d57664e9SAndroid Build Coastguard Worker     }
176*d57664e9SAndroid Build Coastguard Worker 
177*d57664e9SAndroid Build Coastguard Worker     return ze.convertToPtr();
178*d57664e9SAndroid Build Coastguard Worker }
179*d57664e9SAndroid Build Coastguard Worker 
nextEntry(void * cookie)180*d57664e9SAndroid Build Coastguard Worker ZipEntryRO ZipFileRO::nextEntry(void* cookie) {
181*d57664e9SAndroid Build Coastguard Worker     auto result = nextEntryOrError(cookie);
182*d57664e9SAndroid Build Coastguard Worker     if (!result.ok()) {
183*d57664e9SAndroid Build Coastguard Worker         return nullptr;
184*d57664e9SAndroid Build Coastguard Worker     }
185*d57664e9SAndroid Build Coastguard Worker     return result.value();
186*d57664e9SAndroid Build Coastguard Worker }
187*d57664e9SAndroid Build Coastguard Worker 
nextEntryOrError(void * cookie)188*d57664e9SAndroid Build Coastguard Worker base::expected<ZipEntryRO, int32_t> ZipFileRO::nextEntryOrError(void* cookie) {
189*d57664e9SAndroid Build Coastguard Worker     _ZipEntryRO* ze = reinterpret_cast<_ZipEntryRO*>(cookie);
190*d57664e9SAndroid Build Coastguard Worker     int32_t error = Next(ze->cookie, &(ze->entry), &(ze->name));
191*d57664e9SAndroid Build Coastguard Worker     if (error) {
192*d57664e9SAndroid Build Coastguard Worker         if (error != -1) {
193*d57664e9SAndroid Build Coastguard Worker             ALOGW("Error iteration over %s: %s", mFileName != NULL ? mFileName : "<null>",
194*d57664e9SAndroid Build Coastguard Worker                     ErrorCodeString(error));
195*d57664e9SAndroid Build Coastguard Worker             return base::unexpected(error);
196*d57664e9SAndroid Build Coastguard Worker         }
197*d57664e9SAndroid Build Coastguard Worker         return nullptr;
198*d57664e9SAndroid Build Coastguard Worker     }
199*d57664e9SAndroid Build Coastguard Worker 
200*d57664e9SAndroid Build Coastguard Worker     return &(ze->entry);
201*d57664e9SAndroid Build Coastguard Worker }
202*d57664e9SAndroid Build Coastguard Worker 
endIteration(void * cookie)203*d57664e9SAndroid Build Coastguard Worker void ZipFileRO::endIteration(void* cookie)
204*d57664e9SAndroid Build Coastguard Worker {
205*d57664e9SAndroid Build Coastguard Worker     delete reinterpret_cast<_ZipEntryRO*>(cookie);
206*d57664e9SAndroid Build Coastguard Worker }
207*d57664e9SAndroid Build Coastguard Worker 
releaseEntry(ZipEntryRO entry) const208*d57664e9SAndroid Build Coastguard Worker void ZipFileRO::releaseEntry(ZipEntryRO entry) const
209*d57664e9SAndroid Build Coastguard Worker {
210*d57664e9SAndroid Build Coastguard Worker     delete reinterpret_cast<_ZipEntryRO*>(entry);
211*d57664e9SAndroid Build Coastguard Worker }
212*d57664e9SAndroid Build Coastguard Worker 
213*d57664e9SAndroid Build Coastguard Worker /*
214*d57664e9SAndroid Build Coastguard Worker  * Copy the entry's filename to the buffer.
215*d57664e9SAndroid Build Coastguard Worker  */
getEntryFileName(ZipEntryRO entry,char * buffer,size_t bufLen) const216*d57664e9SAndroid Build Coastguard Worker int ZipFileRO::getEntryFileName(ZipEntryRO entry, char* buffer, size_t bufLen)
217*d57664e9SAndroid Build Coastguard Worker     const
218*d57664e9SAndroid Build Coastguard Worker {
219*d57664e9SAndroid Build Coastguard Worker     const _ZipEntryRO* zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);
220*d57664e9SAndroid Build Coastguard Worker     const uint16_t requiredSize = zipEntry->name.length() + 1;
221*d57664e9SAndroid Build Coastguard Worker 
222*d57664e9SAndroid Build Coastguard Worker     if (bufLen < requiredSize) {
223*d57664e9SAndroid Build Coastguard Worker         ALOGW("Buffer too short, requires %d bytes for entry name", requiredSize);
224*d57664e9SAndroid Build Coastguard Worker         return requiredSize;
225*d57664e9SAndroid Build Coastguard Worker     }
226*d57664e9SAndroid Build Coastguard Worker 
227*d57664e9SAndroid Build Coastguard Worker     memcpy(buffer, zipEntry->name.data(), requiredSize - 1);
228*d57664e9SAndroid Build Coastguard Worker     buffer[requiredSize - 1] = '\0';
229*d57664e9SAndroid Build Coastguard Worker 
230*d57664e9SAndroid Build Coastguard Worker     return 0;
231*d57664e9SAndroid Build Coastguard Worker }
232*d57664e9SAndroid Build Coastguard Worker 
233*d57664e9SAndroid Build Coastguard Worker /*
234*d57664e9SAndroid Build Coastguard Worker  * Create a new FileMap object that spans the data in "entry".
235*d57664e9SAndroid Build Coastguard Worker  */
createEntryFileMap(ZipEntryRO entry) const236*d57664e9SAndroid Build Coastguard Worker FileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const
237*d57664e9SAndroid Build Coastguard Worker {
238*d57664e9SAndroid Build Coastguard Worker     const _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);
239*d57664e9SAndroid Build Coastguard Worker     const ZipEntry& ze = zipEntry->entry;
240*d57664e9SAndroid Build Coastguard Worker     int fd = GetFileDescriptor(mHandle);
241*d57664e9SAndroid Build Coastguard Worker     size_t actualLen = 0;
242*d57664e9SAndroid Build Coastguard Worker 
243*d57664e9SAndroid Build Coastguard Worker     if (ze.method == kCompressStored) {
244*d57664e9SAndroid Build Coastguard Worker         actualLen = ze.uncompressed_length;
245*d57664e9SAndroid Build Coastguard Worker     } else {
246*d57664e9SAndroid Build Coastguard Worker         actualLen = ze.compressed_length;
247*d57664e9SAndroid Build Coastguard Worker     }
248*d57664e9SAndroid Build Coastguard Worker 
249*d57664e9SAndroid Build Coastguard Worker     FileMap* newMap = new FileMap();
250*d57664e9SAndroid Build Coastguard Worker     if (!newMap->create(mFileName, fd, ze.offset, actualLen, true)) {
251*d57664e9SAndroid Build Coastguard Worker         delete newMap;
252*d57664e9SAndroid Build Coastguard Worker         return NULL;
253*d57664e9SAndroid Build Coastguard Worker     }
254*d57664e9SAndroid Build Coastguard Worker 
255*d57664e9SAndroid Build Coastguard Worker     return newMap;
256*d57664e9SAndroid Build Coastguard Worker }
257*d57664e9SAndroid Build Coastguard Worker 
258*d57664e9SAndroid Build Coastguard Worker /*
259*d57664e9SAndroid Build Coastguard Worker  * Create a new incfs::IncFsFileMap object that spans the data in "entry".
260*d57664e9SAndroid Build Coastguard Worker  */
createEntryIncFsFileMap(ZipEntryRO entry) const261*d57664e9SAndroid Build Coastguard Worker std::optional<incfs::IncFsFileMap> ZipFileRO::createEntryIncFsFileMap(ZipEntryRO entry) const
262*d57664e9SAndroid Build Coastguard Worker {
263*d57664e9SAndroid Build Coastguard Worker     const _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);
264*d57664e9SAndroid Build Coastguard Worker     const ZipEntry& ze = zipEntry->entry;
265*d57664e9SAndroid Build Coastguard Worker     int fd = GetFileDescriptor(mHandle);
266*d57664e9SAndroid Build Coastguard Worker     size_t actualLen = 0;
267*d57664e9SAndroid Build Coastguard Worker 
268*d57664e9SAndroid Build Coastguard Worker     if (ze.method == kCompressStored) {
269*d57664e9SAndroid Build Coastguard Worker         actualLen = ze.uncompressed_length;
270*d57664e9SAndroid Build Coastguard Worker     } else {
271*d57664e9SAndroid Build Coastguard Worker         actualLen = ze.compressed_length;
272*d57664e9SAndroid Build Coastguard Worker     }
273*d57664e9SAndroid Build Coastguard Worker 
274*d57664e9SAndroid Build Coastguard Worker     incfs::IncFsFileMap newMap;
275*d57664e9SAndroid Build Coastguard Worker     if (!newMap.Create(fd, ze.offset, actualLen, mFileName)) {
276*d57664e9SAndroid Build Coastguard Worker         return std::nullopt;
277*d57664e9SAndroid Build Coastguard Worker     }
278*d57664e9SAndroid Build Coastguard Worker     return std::move(newMap);
279*d57664e9SAndroid Build Coastguard Worker }
280*d57664e9SAndroid Build Coastguard Worker 
281*d57664e9SAndroid Build Coastguard Worker /*
282*d57664e9SAndroid Build Coastguard Worker  * Uncompress an entry, in its entirety, into the provided output buffer.
283*d57664e9SAndroid Build Coastguard Worker  *
284*d57664e9SAndroid Build Coastguard Worker  * This doesn't verify the data's CRC, which might be useful for
285*d57664e9SAndroid Build Coastguard Worker  * uncompressed data.  The caller should be able to manage it.
286*d57664e9SAndroid Build Coastguard Worker  */
uncompressEntry(ZipEntryRO entry,void * buffer,size_t size) const287*d57664e9SAndroid Build Coastguard Worker bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer, size_t size) const
288*d57664e9SAndroid Build Coastguard Worker {
289*d57664e9SAndroid Build Coastguard Worker     _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);
290*d57664e9SAndroid Build Coastguard Worker     const int32_t error = ExtractToMemory(mHandle, &(zipEntry->entry),
291*d57664e9SAndroid Build Coastguard Worker         (uint8_t*) buffer, size);
292*d57664e9SAndroid Build Coastguard Worker     if (error) {
293*d57664e9SAndroid Build Coastguard Worker         ALOGW("ExtractToMemory failed with %s", ErrorCodeString(error));
294*d57664e9SAndroid Build Coastguard Worker         return false;
295*d57664e9SAndroid Build Coastguard Worker     }
296*d57664e9SAndroid Build Coastguard Worker 
297*d57664e9SAndroid Build Coastguard Worker     return true;
298*d57664e9SAndroid Build Coastguard Worker }
299*d57664e9SAndroid Build Coastguard Worker 
300*d57664e9SAndroid Build Coastguard Worker /*
301*d57664e9SAndroid Build Coastguard Worker  * Uncompress an entry, in its entirety, to an open file descriptor.
302*d57664e9SAndroid Build Coastguard Worker  *
303*d57664e9SAndroid Build Coastguard Worker  * This doesn't verify the data's CRC, but probably should.
304*d57664e9SAndroid Build Coastguard Worker  */
uncompressEntry(ZipEntryRO entry,int fd) const305*d57664e9SAndroid Build Coastguard Worker bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const
306*d57664e9SAndroid Build Coastguard Worker {
307*d57664e9SAndroid Build Coastguard Worker     _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);
308*d57664e9SAndroid Build Coastguard Worker     const int32_t error = ExtractEntryToFile(mHandle, &(zipEntry->entry), fd);
309*d57664e9SAndroid Build Coastguard Worker     if (error) {
310*d57664e9SAndroid Build Coastguard Worker         ALOGW("ExtractToFile failed with %s", ErrorCodeString(error));
311*d57664e9SAndroid Build Coastguard Worker         return false;
312*d57664e9SAndroid Build Coastguard Worker     }
313*d57664e9SAndroid Build Coastguard Worker 
314*d57664e9SAndroid Build Coastguard Worker     return true;
315*d57664e9SAndroid Build Coastguard Worker }
316*d57664e9SAndroid Build Coastguard Worker 
getZipFileName()317*d57664e9SAndroid Build Coastguard Worker const char* ZipFileRO::getZipFileName() {
318*d57664e9SAndroid Build Coastguard Worker     return mFileName;
319*d57664e9SAndroid Build Coastguard Worker }
320