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