11f5762e646bed2290934280464832782766ee68eMathias Agopian/* 21f5762e646bed2290934280464832782766ee68eMathias Agopian * Copyright (C) 2007 The Android Open Source Project 31f5762e646bed2290934280464832782766ee68eMathias Agopian * 41f5762e646bed2290934280464832782766ee68eMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 51f5762e646bed2290934280464832782766ee68eMathias Agopian * you may not use this file except in compliance with the License. 61f5762e646bed2290934280464832782766ee68eMathias Agopian * You may obtain a copy of the License at 71f5762e646bed2290934280464832782766ee68eMathias Agopian * 81f5762e646bed2290934280464832782766ee68eMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 91f5762e646bed2290934280464832782766ee68eMathias Agopian * 101f5762e646bed2290934280464832782766ee68eMathias Agopian * Unless required by applicable law or agreed to in writing, software 111f5762e646bed2290934280464832782766ee68eMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 121f5762e646bed2290934280464832782766ee68eMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131f5762e646bed2290934280464832782766ee68eMathias Agopian * See the License for the specific language governing permissions and 141f5762e646bed2290934280464832782766ee68eMathias Agopian * limitations under the License. 151f5762e646bed2290934280464832782766ee68eMathias Agopian */ 161f5762e646bed2290934280464832782766ee68eMathias Agopian 171f5762e646bed2290934280464832782766ee68eMathias Agopian// 181f5762e646bed2290934280464832782766ee68eMathias Agopian// Read-only access to Zip archives, with minimal heap allocation. 191f5762e646bed2290934280464832782766ee68eMathias Agopian// 201f5762e646bed2290934280464832782766ee68eMathias Agopian#define LOG_TAG "zipro" 211f5762e646bed2290934280464832782766ee68eMathias Agopian//#define LOG_NDEBUG 0 221f5762e646bed2290934280464832782766ee68eMathias Agopian#include <androidfw/ZipFileRO.h> 231f5762e646bed2290934280464832782766ee68eMathias Agopian#include <utils/Log.h> 241f5762e646bed2290934280464832782766ee68eMathias Agopian#include <utils/Compat.h> 251f5762e646bed2290934280464832782766ee68eMathias Agopian#include <utils/misc.h> 261f5762e646bed2290934280464832782766ee68eMathias Agopian#include <utils/threads.h> 27afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath#include <ziparchive/zip_archive.h> 281f5762e646bed2290934280464832782766ee68eMathias Agopian 291f5762e646bed2290934280464832782766ee68eMathias Agopian#include <zlib.h> 301f5762e646bed2290934280464832782766ee68eMathias Agopian 311f5762e646bed2290934280464832782766ee68eMathias Agopian#include <string.h> 321f5762e646bed2290934280464832782766ee68eMathias Agopian#include <fcntl.h> 331f5762e646bed2290934280464832782766ee68eMathias Agopian#include <errno.h> 341f5762e646bed2290934280464832782766ee68eMathias Agopian#include <assert.h> 351f5762e646bed2290934280464832782766ee68eMathias Agopian#include <unistd.h> 361f5762e646bed2290934280464832782766ee68eMathias Agopian 371f5762e646bed2290934280464832782766ee68eMathias Agopianusing namespace android; 381f5762e646bed2290934280464832782766ee68eMathias Agopian 39afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamathclass _ZipEntryRO { 40afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamathpublic: 41afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath ZipEntry entry; 42f162faaa1266ad38c293e1e54911e389f39c2654Yusuke Sato ZipString name; 43afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath void *cookie; 441f5762e646bed2290934280464832782766ee68eMathias Agopian 45e2134a4b5dafc37f2de7e9b4190819f24aac207cPiotr Jastrzebski _ZipEntryRO() : cookie(NULL) {} 461f5762e646bed2290934280464832782766ee68eMathias Agopian 471a68b079d714b1de52775e1153359f2867340754Piotr Jastrzebski ~_ZipEntryRO() { 481a68b079d714b1de52775e1153359f2867340754Piotr Jastrzebski EndIteration(cookie); 491a68b079d714b1de52775e1153359f2867340754Piotr Jastrzebski } 501a68b079d714b1de52775e1153359f2867340754Piotr Jastrzebski 51afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamathprivate: 52afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath _ZipEntryRO(const _ZipEntryRO& other); 53afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath _ZipEntryRO& operator=(const _ZipEntryRO& other); 54afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath}; 551f5762e646bed2290934280464832782766ee68eMathias Agopian 56afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan KamathZipFileRO::~ZipFileRO() { 57afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath CloseArchive(mHandle); 58afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath free(mFileName); 591f5762e646bed2290934280464832782766ee68eMathias Agopian} 601f5762e646bed2290934280464832782766ee68eMathias Agopian 611f5762e646bed2290934280464832782766ee68eMathias Agopian/* 621f5762e646bed2290934280464832782766ee68eMathias Agopian * Open the specified file read-only. We memory-map the entire thing and 631f5762e646bed2290934280464832782766ee68eMathias Agopian * close the file before returning. 641f5762e646bed2290934280464832782766ee68eMathias Agopian */ 65afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath/* static */ ZipFileRO* ZipFileRO::open(const char* zipFileName) 661f5762e646bed2290934280464832782766ee68eMathias Agopian{ 67afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath ZipArchiveHandle handle; 68afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath const int32_t error = OpenArchive(zipFileName, &handle); 69afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (error) { 70afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath ALOGW("Error opening archive %s: %s", zipFileName, ErrorCodeString(error)); 715a7587fa90732c013bb9266f1bdae0a557455c15Narayan Kamath CloseArchive(handle); 72afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath return NULL; 731f5762e646bed2290934280464832782766ee68eMathias Agopian } 741f5762e646bed2290934280464832782766ee68eMathias Agopian 75afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath return new ZipFileRO(handle, strdup(zipFileName)); 76afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath} 771f5762e646bed2290934280464832782766ee68eMathias Agopian 781f5762e646bed2290934280464832782766ee68eMathias Agopian 79afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan KamathZipEntryRO ZipFileRO::findEntryByName(const char* entryName) const 80afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath{ 81afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath _ZipEntryRO* data = new _ZipEntryRO; 82e2134a4b5dafc37f2de7e9b4190819f24aac207cPiotr Jastrzebski 83f162faaa1266ad38c293e1e54911e389f39c2654Yusuke Sato data->name = ZipString(entryName); 84e2134a4b5dafc37f2de7e9b4190819f24aac207cPiotr Jastrzebski 85e2134a4b5dafc37f2de7e9b4190819f24aac207cPiotr Jastrzebski const int32_t error = FindEntry(mHandle, data->name, &(data->entry)); 86afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (error) { 87afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath delete data; 88afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath return NULL; 891f5762e646bed2290934280464832782766ee68eMathias Agopian } 901f5762e646bed2290934280464832782766ee68eMathias Agopian 91afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath return (ZipEntryRO) data; 921f5762e646bed2290934280464832782766ee68eMathias Agopian} 931f5762e646bed2290934280464832782766ee68eMathias Agopian 941f5762e646bed2290934280464832782766ee68eMathias Agopian/* 95afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath * Get the useful fields from the zip entry. 96afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath * 97afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath * Returns "false" if the offsets to the fields or the contents of the fields 98afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath * appear to be bogus. 991f5762e646bed2290934280464832782766ee68eMathias Agopian */ 1004600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamathbool ZipFileRO::getEntryInfo(ZipEntryRO entry, uint16_t* pMethod, 1014600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset, 1024600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath uint32_t* pModWhen, uint32_t* pCrc32) const 1031f5762e646bed2290934280464832782766ee68eMathias Agopian{ 104afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath const _ZipEntryRO* zipEntry = reinterpret_cast<_ZipEntryRO*>(entry); 105afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath const ZipEntry& ze = zipEntry->entry; 1061f5762e646bed2290934280464832782766ee68eMathias Agopian 107afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (pMethod != NULL) { 108afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath *pMethod = ze.method; 1091f5762e646bed2290934280464832782766ee68eMathias Agopian } 110afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (pUncompLen != NULL) { 111afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath *pUncompLen = ze.uncompressed_length; 1121f5762e646bed2290934280464832782766ee68eMathias Agopian } 113afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (pCompLen != NULL) { 114afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath *pCompLen = ze.compressed_length; 1151f5762e646bed2290934280464832782766ee68eMathias Agopian } 116afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (pOffset != NULL) { 117afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath *pOffset = ze.offset; 1181f5762e646bed2290934280464832782766ee68eMathias Agopian } 119afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (pModWhen != NULL) { 120afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath *pModWhen = ze.mod_time; 1211f5762e646bed2290934280464832782766ee68eMathias Agopian } 122afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (pCrc32 != NULL) { 123afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath *pCrc32 = ze.crc32; 1241f5762e646bed2290934280464832782766ee68eMathias Agopian } 1251f5762e646bed2290934280464832782766ee68eMathias Agopian 1261f5762e646bed2290934280464832782766ee68eMathias Agopian return true; 1271f5762e646bed2290934280464832782766ee68eMathias Agopian} 1281f5762e646bed2290934280464832782766ee68eMathias Agopian 12934fe3df8519523dbb4bc27010fa57f259d5e868dYusuke Satobool ZipFileRO::startIteration(void** cookie) { 13034fe3df8519523dbb4bc27010fa57f259d5e868dYusuke Sato return startIteration(cookie, NULL, NULL); 13134fe3df8519523dbb4bc27010fa57f259d5e868dYusuke Sato} 13234fe3df8519523dbb4bc27010fa57f259d5e868dYusuke Sato 13334fe3df8519523dbb4bc27010fa57f259d5e868dYusuke Satobool ZipFileRO::startIteration(void** cookie, const char* prefix, const char* suffix) 1341f5762e646bed2290934280464832782766ee68eMathias Agopian{ 135afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath _ZipEntryRO* ze = new _ZipEntryRO; 13653a19bb967f45ddfb80699865dc30094024343f6Yusuke Sato ZipString pe(prefix ? prefix : ""); 13753a19bb967f45ddfb80699865dc30094024343f6Yusuke Sato ZipString se(suffix ? suffix : ""); 13834fe3df8519523dbb4bc27010fa57f259d5e868dYusuke Sato int32_t error = StartIteration(mHandle, &(ze->cookie), 13934fe3df8519523dbb4bc27010fa57f259d5e868dYusuke Sato prefix ? &pe : NULL, 14034fe3df8519523dbb4bc27010fa57f259d5e868dYusuke Sato suffix ? &se : NULL); 141afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (error) { 142afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath ALOGW("Could not start iteration over %s: %s", mFileName, ErrorCodeString(error)); 143afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath delete ze; 144afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath return false; 1451f5762e646bed2290934280464832782766ee68eMathias Agopian } 1461f5762e646bed2290934280464832782766ee68eMathias Agopian 147afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath *cookie = ze; 148afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath return true; 1491f5762e646bed2290934280464832782766ee68eMathias Agopian} 1501f5762e646bed2290934280464832782766ee68eMathias Agopian 151afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan KamathZipEntryRO ZipFileRO::nextEntry(void* cookie) 1521f5762e646bed2290934280464832782766ee68eMathias Agopian{ 153afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath _ZipEntryRO* ze = reinterpret_cast<_ZipEntryRO*>(cookie); 154afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath int32_t error = Next(ze->cookie, &(ze->entry), &(ze->name)); 155afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (error) { 156afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (error != -1) { 157afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath ALOGW("Error iteration over %s: %s", mFileName, ErrorCodeString(error)); 1581f5762e646bed2290934280464832782766ee68eMathias Agopian } 159afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath return NULL; 1601f5762e646bed2290934280464832782766ee68eMathias Agopian } 1611f5762e646bed2290934280464832782766ee68eMathias Agopian 162afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath return &(ze->entry); 1631f5762e646bed2290934280464832782766ee68eMathias Agopian} 1641f5762e646bed2290934280464832782766ee68eMathias Agopian 165afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamathvoid ZipFileRO::endIteration(void* cookie) 1661f5762e646bed2290934280464832782766ee68eMathias Agopian{ 167afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath delete reinterpret_cast<_ZipEntryRO*>(cookie); 1681f5762e646bed2290934280464832782766ee68eMathias Agopian} 1691f5762e646bed2290934280464832782766ee68eMathias Agopian 170afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamathvoid ZipFileRO::releaseEntry(ZipEntryRO entry) const 1711f5762e646bed2290934280464832782766ee68eMathias Agopian{ 172afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath delete reinterpret_cast<_ZipEntryRO*>(entry); 1731f5762e646bed2290934280464832782766ee68eMathias Agopian} 1741f5762e646bed2290934280464832782766ee68eMathias Agopian 1751f5762e646bed2290934280464832782766ee68eMathias Agopian/* 1761f5762e646bed2290934280464832782766ee68eMathias Agopian * Copy the entry's filename to the buffer. 1771f5762e646bed2290934280464832782766ee68eMathias Agopian */ 1784600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamathint ZipFileRO::getEntryFileName(ZipEntryRO entry, char* buffer, size_t bufLen) 1791f5762e646bed2290934280464832782766ee68eMathias Agopian const 1801f5762e646bed2290934280464832782766ee68eMathias Agopian{ 181afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath const _ZipEntryRO* zipEntry = reinterpret_cast<_ZipEntryRO*>(entry); 182afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath const uint16_t requiredSize = zipEntry->name.name_length + 1; 1831f5762e646bed2290934280464832782766ee68eMathias Agopian 184afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (bufLen < requiredSize) { 185afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath ALOGW("Buffer too short, requires %d bytes for entry name", requiredSize); 186afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath return requiredSize; 187afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath } 188afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath 189afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath memcpy(buffer, zipEntry->name.name, requiredSize - 1); 190afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath buffer[requiredSize - 1] = '\0'; 1911f5762e646bed2290934280464832782766ee68eMathias Agopian 1921f5762e646bed2290934280464832782766ee68eMathias Agopian return 0; 1931f5762e646bed2290934280464832782766ee68eMathias Agopian} 1941f5762e646bed2290934280464832782766ee68eMathias Agopian 1951f5762e646bed2290934280464832782766ee68eMathias Agopian/* 1961f5762e646bed2290934280464832782766ee68eMathias Agopian * Create a new FileMap object that spans the data in "entry". 1971f5762e646bed2290934280464832782766ee68eMathias Agopian */ 1981f5762e646bed2290934280464832782766ee68eMathias AgopianFileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const 1991f5762e646bed2290934280464832782766ee68eMathias Agopian{ 200afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath const _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry); 201afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath const ZipEntry& ze = zipEntry->entry; 202afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath int fd = GetFileDescriptor(mHandle); 203afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath size_t actualLen = 0; 2040d6c2d7b9db209d740992045dd3b842e52306598Kenny Root 205afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (ze.method == kCompressStored) { 206afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath actualLen = ze.uncompressed_length; 2070d6c2d7b9db209d740992045dd3b842e52306598Kenny Root } else { 208afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath actualLen = ze.compressed_length; 2090d6c2d7b9db209d740992045dd3b842e52306598Kenny Root } 2101f5762e646bed2290934280464832782766ee68eMathias Agopian 211afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath FileMap* newMap = new FileMap(); 212afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (!newMap->create(mFileName, fd, ze.offset, actualLen, true)) { 213688ff4cf0f93d1a886437884f23874e5595d59a3Narayan Kamath delete newMap; 2141f5762e646bed2290934280464832782766ee68eMathias Agopian return NULL; 2151f5762e646bed2290934280464832782766ee68eMathias Agopian } 2161f5762e646bed2290934280464832782766ee68eMathias Agopian 2171f5762e646bed2290934280464832782766ee68eMathias Agopian return newMap; 2181f5762e646bed2290934280464832782766ee68eMathias Agopian} 2191f5762e646bed2290934280464832782766ee68eMathias Agopian 2201f5762e646bed2290934280464832782766ee68eMathias Agopian/* 2211f5762e646bed2290934280464832782766ee68eMathias Agopian * Uncompress an entry, in its entirety, into the provided output buffer. 2221f5762e646bed2290934280464832782766ee68eMathias Agopian * 2231f5762e646bed2290934280464832782766ee68eMathias Agopian * This doesn't verify the data's CRC, which might be useful for 2241f5762e646bed2290934280464832782766ee68eMathias Agopian * uncompressed data. The caller should be able to manage it. 2251f5762e646bed2290934280464832782766ee68eMathias Agopian */ 226afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamathbool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer, size_t size) const 2271f5762e646bed2290934280464832782766ee68eMathias Agopian{ 228afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry); 229afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath const int32_t error = ExtractToMemory(mHandle, &(zipEntry->entry), 230afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath (uint8_t*) buffer, size); 231afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (error) { 232afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath ALOGW("ExtractToMemory failed with %s", ErrorCodeString(error)); 2330d6c2d7b9db209d740992045dd3b842e52306598Kenny Root return false; 2340d6c2d7b9db209d740992045dd3b842e52306598Kenny Root } 2351f5762e646bed2290934280464832782766ee68eMathias Agopian 236afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath return true; 2371f5762e646bed2290934280464832782766ee68eMathias Agopian} 2381f5762e646bed2290934280464832782766ee68eMathias Agopian 2391f5762e646bed2290934280464832782766ee68eMathias Agopian/* 2401f5762e646bed2290934280464832782766ee68eMathias Agopian * Uncompress an entry, in its entirety, to an open file descriptor. 2411f5762e646bed2290934280464832782766ee68eMathias Agopian * 2421f5762e646bed2290934280464832782766ee68eMathias Agopian * This doesn't verify the data's CRC, but probably should. 2431f5762e646bed2290934280464832782766ee68eMathias Agopian */ 2441f5762e646bed2290934280464832782766ee68eMathias Agopianbool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const 2451f5762e646bed2290934280464832782766ee68eMathias Agopian{ 246afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry); 247afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath const int32_t error = ExtractEntryToFile(mHandle, &(zipEntry->entry), fd); 248afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (error) { 249afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath ALOGW("ExtractToMemory failed with %s", ErrorCodeString(error)); 2500d6c2d7b9db209d740992045dd3b842e52306598Kenny Root return false; 2510d6c2d7b9db209d740992045dd3b842e52306598Kenny Root } 2521f5762e646bed2290934280464832782766ee68eMathias Agopian 253afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath return true; 2541f5762e646bed2290934280464832782766ee68eMathias Agopian} 255