19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Provide access to a read-only asset. 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "asset" 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define NDEBUG 0 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <androidfw/Asset.h> 25b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <androidfw/StreamingZipInflater.h> 261f5762e646bed2290934280464832782766ee68eMathias Agopian#include <androidfw/ZipFileRO.h> 271f5762e646bed2290934280464832782766ee68eMathias Agopian#include <androidfw/ZipUtils.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Atomic.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/FileMap.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 3182e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn#include <utils/threads.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <assert.h> 34b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <errno.h> 35b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <fcntl.h> 36b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <memory.h> 37b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <string.h> 38ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root#include <sys/stat.h> 39ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root#include <sys/types.h> 40b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <unistd.h> 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef O_BINARY 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project# define O_BINARY 0 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4882e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackbornstatic Mutex gAssetLock; 4982e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackbornstatic int32_t gCount = 0; 5082e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackbornstatic Asset* gHead = NULL; 5182e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackbornstatic Asset* gTail = NULL; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t Asset::getGlobalCount() 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5582e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn AutoMutex _l(gAssetLock); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return gCount; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5982e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne HackbornString8 Asset::getAssetAllocations() 6082e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn{ 6182e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn AutoMutex _l(gAssetLock); 6282e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn String8 res; 6382e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn Asset* cur = gHead; 6482e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn while (cur != NULL) { 6582e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn if (cur->isAllocated()) { 6682e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn res.append(" "); 6782e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn res.append(cur->getAssetSource()); 68ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root off64_t size = (cur->getLength()+512)/1024; 6982e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn char buf[64]; 7082e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn sprintf(buf, ": %dK\n", (int)size); 7182e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn res.append(buf); 7282e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn } 7382e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn cur = cur->mNext; 7482e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn } 7500adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn 7682e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn return res; 7782e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn} 7882e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAsset::Asset(void) 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mAccessMode(ACCESS_UNKNOWN) 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8282e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn AutoMutex _l(gAssetLock); 8382e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn gCount++; 8482e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn mNext = mPrev = NULL; 8582e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn if (gTail == NULL) { 8682e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn gHead = gTail = this; 8700adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn } else { 8800adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn mPrev = gTail; 8900adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn gTail->mNext = this; 9000adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn gTail = this; 9100adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn } 926215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Creating Asset %p #%d\n", this, gCount); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAsset::~Asset(void) 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9782e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn AutoMutex _l(gAssetLock); 9800adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn gCount--; 9982e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn if (gHead == this) { 10082e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn gHead = mNext; 10182e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn } 10282e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn if (gTail == this) { 10382e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn gTail = mPrev; 10482e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn } 10582e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn if (mNext != NULL) { 10682e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn mNext->mPrev = mPrev; 10782e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn } 10882e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn if (mPrev != NULL) { 10982e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn mPrev->mNext = mNext; 11082e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn } 11182e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7Dianne Hackborn mNext = mPrev = NULL; 1126215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Destroying Asset in %p #%d\n", this, gCount); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new Asset from a file on disk. There is a fair chance that 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the file doesn't actually exist. 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * We can use "mode" to decide how we want to go about it. 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*static*/ Asset* Asset::createFromFile(const char* fileName, AccessMode mode) 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _FileAsset* pAsset; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result; 125ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root off64_t length; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = open(fileName, O_RDONLY | O_BINARY); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd < 0) 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Under Linux, the lseek fails if we actually opened a directory. To 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be correct we should test the file type explicitly, but since we 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * always open things read-only it doesn't really matter, so there's 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * no value in incurring the extra overhead of an fstat() call. 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 138ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root // TODO(kroot): replace this with fstat despite the plea above. 139ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root#if 1 140ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root length = lseek64(fd, 0, SEEK_END); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (length < 0) { 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ::close(fd); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 145ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root (void) lseek64(fd, 0, SEEK_SET); 146ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root#else 147ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root struct stat st; 148ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root if (fstat(fd, &st) < 0) { 149ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root ::close(fd); 150ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root return NULL; 151ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root } 152ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root 153ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root if (!S_ISREG(st.st_mode)) { 154ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root ::close(fd); 155ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root return NULL; 156ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root } 157ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root#endif 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pAsset = new _FileAsset; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = pAsset->openChunk(fileName, fd, 0, length); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete pAsset; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pAsset->mAccessMode = mode; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pAsset; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new Asset from a compressed file on disk. There is a fair chance 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that the file doesn't actually exist. 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * We currently support gzip files. We might want to handle .bz2 someday. 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*static*/ Asset* Asset::createFromCompressedFile(const char* fileName, 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AccessMode mode) 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _CompressedAsset* pAsset; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result; 182ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root off64_t fileLen; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool scanResult; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long offset; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int method; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long uncompressedLen, compressedLen; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = open(fileName, O_RDONLY | O_BINARY); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd < 0) 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fileLen = lseek(fd, 0, SEEK_END); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileLen < 0) { 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ::close(fd); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void) lseek(fd, 0, SEEK_SET); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* want buffered I/O for the file scan; must dup so fclose() is safe */ 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FILE* fp = fdopen(dup(fd), "rb"); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fp == NULL) { 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ::close(fd); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned long crc32; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scanResult = ZipUtils::examineGzip(fp, &method, &uncompressedLen, 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project &compressedLen, &crc32); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset = ftell(fp); 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fclose(fp); 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!scanResult) { 2135baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("File '%s' is not in gzip format\n", fileName); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ::close(fd); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pAsset = new _CompressedAsset; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = pAsset->openChunk(fd, offset, method, uncompressedLen, 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project compressedLen); 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) { 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete pAsset; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pAsset->mAccessMode = mode; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pAsset; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new Asset from part of an open file. 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 235ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root/*static*/ Asset* Asset::createFromFileSegment(int fd, off64_t offset, 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t length, AccessMode mode) 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _FileAsset* pAsset; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result; 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pAsset = new _FileAsset; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = pAsset->openChunk(NULL, fd, offset, length); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pAsset->mAccessMode = mode; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pAsset; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new Asset from compressed data in an open file. 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 253ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root/*static*/ Asset* Asset::createFromCompressedData(int fd, off64_t offset, 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int compressionMethod, size_t uncompressedLen, size_t compressedLen, 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AccessMode mode) 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _CompressedAsset* pAsset; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pAsset = new _CompressedAsset; 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = pAsset->openChunk(fd, offset, compressionMethod, 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uncompressedLen, compressedLen); 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pAsset->mAccessMode = mode; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pAsset; 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new Asset from a memory mapping. 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*static*/ Asset* Asset::createFromUncompressedMap(FileMap* dataMap, 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AccessMode mode) 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _FileAsset* pAsset; 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result; 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pAsset = new _FileAsset; 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = pAsset->openChunk(dataMap); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pAsset->mAccessMode = mode; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pAsset; 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new Asset from compressed data in a memory mapping. 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*static*/ Asset* Asset::createFromCompressedMap(FileMap* dataMap, 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int method, size_t uncompressedLen, AccessMode mode) 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _CompressedAsset* pAsset; 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pAsset = new _CompressedAsset; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = pAsset->openChunk(dataMap, method, uncompressedLen); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pAsset->mAccessMode = mode; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pAsset; 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Do generic seek() housekeeping. Pass in the offset/whence values from 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the seek request, along with the current chunk offset and the chunk 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * length. 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the new chunk offset, or -1 if the seek is illegal. 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 315ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Rootoff64_t Asset::handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn) 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 317ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root off64_t newOffset; 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (whence) { 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SEEK_SET: 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newOffset = offset; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SEEK_CUR: 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newOffset = curPosn + offset; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SEEK_END: 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newOffset = maxPosn + offset; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 3308564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("unexpected whence %d\n", whence); 331ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root // this was happening due to an off64_t size mismatch 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(false); 333ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root return (off64_t) -1; 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newOffset < 0 || newOffset > maxPosn) { 3378564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("seek out of range: want %ld, end=%ld\n", 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (long) newOffset, (long) maxPosn); 339ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root return (off64_t) -1; 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return newOffset; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * =========================================================================== 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * _FileAsset 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * =========================================================================== 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructor. 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project_FileAsset::_FileAsset(void) 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mStart(0), mLength(0), mOffset(0), mFp(NULL), mFileName(NULL), mMap(NULL), mBuf(NULL) 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Destructor. Release resources. 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project_FileAsset::~_FileAsset(void) 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Operate on a chunk of an uncompressed file. 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Zero-length chunks are allowed. 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 373ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Rootstatus_t _FileAsset::openChunk(const char* fileName, int fd, off64_t offset, size_t length) 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mFp == NULL); // no reopen 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mMap == NULL); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(fd >= 0); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(offset >= 0); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Seek to end to get file length. 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 383ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root off64_t fileLength; 384ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root fileLength = lseek64(fd, 0, SEEK_END); 385ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root if (fileLength == (off64_t) -1) { 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // probably a bad file descriptor 3875baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("failed lseek (errno=%d)\n", errno); 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 391ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root if ((off64_t) (offset + length) > fileLength) { 3925baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("start (%ld) + len (%ld) > end (%ld)\n", 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (long) offset, (long) length, (long) fileLength); 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* after fdopen, the fd will be closed on fclose() */ 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFp = fdopen(fd, "rb"); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFp == NULL) 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStart = offset; 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLength = length; 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mOffset == 0); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* seek the FILE* to the start of chunk */ 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fseek(mFp, mStart, SEEK_SET) != 0) { 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(false); 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileName = fileName != NULL ? strdup(fileName) : NULL; 41200adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create the chunk from the map. 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t _FileAsset::openChunk(FileMap* dataMap) 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mFp == NULL); // no reopen 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mMap == NULL); 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(dataMap != NULL); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMap = dataMap; 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStart = -1; // not used 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLength = dataMap->getDataLength(); 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mOffset == 0); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Read a chunk of data. 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t _FileAsset::read(void* buf, size_t count) 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t maxLen; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t actual; 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mOffset >= 0 && mOffset <= mLength); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (getAccessMode() == ACCESS_BUFFER) { 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * On first access, read or map the entire file. The caller has 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * requested buffer access, either because they're going to be 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using the buffer or because what they're doing has appropriate 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * performance needs and access patterns. 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBuf == NULL) 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getBuffer(false); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* adjust count if we're near EOF */ 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project maxLen = mLength - mOffset; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count > maxLen) 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count = maxLen; 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!count) 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMap != NULL) { 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* copy from mapped area */ 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("map read\n"); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(buf, (char*)mMap->getDataPtr() + mOffset, count); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project actual = count; 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mBuf != NULL) { 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* copy from buffer */ 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("buf read\n"); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(buf, (char*)mBuf + mOffset, count); 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project actual = count; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* read from the file */ 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("file read\n"); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ftell(mFp) != mStart + mOffset) { 4763762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Hosed: %ld != %ld+%ld\n", 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ftell(mFp), (long) mStart, (long) mOffset); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(false); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This returns 0 on error or eof. We need to use ferror() or feof() 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to tell the difference, but we don't currently have those on the 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * device. However, we know how much data is *supposed* to be in the 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file, so if we don't read the full amount we know something is 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * hosed. 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project actual = fread(buf, 1, count, mFp); 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (actual == 0) // something failed -- I/O error? 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(actual == count); 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOffset += actual; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return actual; 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Seek to a new position. 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 502ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Rootoff64_t _FileAsset::seek(off64_t offset, int whence) 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 504ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root off64_t newPosn; 505ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root off64_t actualOffset; 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute new position within chunk 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newPosn = handleSeek(offset, whence, mOffset, mLength); 509ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root if (newPosn == (off64_t) -1) 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return newPosn; 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 512ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root actualOffset = mStart + newPosn; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFp != NULL) { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fseek(mFp, (long) actualOffset, SEEK_SET) != 0) 516ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root return (off64_t) -1; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOffset = actualOffset - mStart; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mOffset; 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Close the asset. 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid _FileAsset::close(void) 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMap != NULL) { 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMap->release(); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMap = NULL; 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBuf != NULL) { 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete[] mBuf; 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBuf = NULL; 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileName != NULL) { 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(mFileName); 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileName = NULL; 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 54100adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFp != NULL) { 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // can only be NULL when called from destructor 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (otherwise we would never return this object) 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fclose(mFp); 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFp = NULL; 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return a read-only pointer to a buffer. 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * We can either read the whole thing in or map the relevant piece of 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the source file. Ideally a map would be established at a higher 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * level and we'd be using a different object, but we didn't, so we 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * deal with it here. 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst void* _FileAsset::getBuffer(bool wordAligned) 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* subsequent requests just use what we did previously */ 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBuf != NULL) 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBuf; 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMap != NULL) { 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!wordAligned) { 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mMap->getDataPtr(); 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ensureAlignment(mMap); 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mFp != NULL); 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLength < kReadVsMapThreshold) { 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char* buf; 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long allocLen; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* zero-length files are allowed; not sure about zero-len allocs */ 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* (works fine with gcc + x86linux) */ 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allocLen = mLength; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLength == 0) 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allocLen = 1; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf = new unsigned char[allocLen]; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (buf == NULL) { 5843762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("alloc of %ld bytes failed\n", (long) allocLen); 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 58871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("Asset %p allocating buffer size %d (smaller than threshold)", this, (int)allocLen); 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLength > 0) { 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long oldPosn = ftell(mFp); 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fseek(mFp, mStart, SEEK_SET); 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fread(buf, 1, mLength, mFp) != (size_t) mLength) { 5933762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("failed reading %ld bytes\n", (long) mLength); 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete[] buf; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fseek(mFp, oldPosn, SEEK_SET); 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 60071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV(" getBuffer: loaded into buffer\n"); 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBuf = buf; 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBuf; 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileMap* map; 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project map = new FileMap; 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!map->create(NULL, fileno(mFp), mStart, mLength, true)) { 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project map->release(); 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 61371f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV(" getBuffer: mapped\n"); 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMap = map; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!wordAligned) { 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mMap->getDataPtr(); 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ensureAlignment(mMap); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 623ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Rootint _FileAsset::openFileDescriptor(off64_t* outStart, off64_t* outLength) const 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMap != NULL) { 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* fname = mMap->getFileName(); 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fname == NULL) { 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fname = mFileName; 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fname == NULL) { 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outStart = mMap->getDataOffset(); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outLength = mMap->getDataLength(); 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return open(fname, O_RDONLY | O_BINARY); 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileName == NULL) { 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outStart = mStart; 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outLength = mLength; 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return open(mFileName, O_RDONLY | O_BINARY); 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst void* _FileAsset::ensureAlignment(FileMap* map) 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* data = map->getDataPtr(); 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((((size_t)data)&0x3) == 0) { 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We can return this directly if it is aligned on a word 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // boundary. 65171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("Returning aligned FileAsset %p (%s).", this, 65278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn getAssetSource()); 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return data; 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If not aligned on a word boundary, then we need to copy it into 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // our own buffer. 65771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("Copying FileAsset %p (%s) to buffer size %d to make it aligned.", this, 65878c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn getAssetSource(), (int)mLength); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char* buf = new unsigned char[mLength]; 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (buf == NULL) { 6613762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("alloc of %ld bytes failed\n", (long) mLength); 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(buf, data, mLength); 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBuf = buf; 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return buf; 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * =========================================================================== 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * _CompressedAsset 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * =========================================================================== 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructor. 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project_CompressedAsset::_CompressedAsset(void) 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mStart(0), mCompressedLen(0), mUncompressedLen(0), mOffset(0), 680b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate mMap(NULL), mFd(-1), mZipInflater(NULL), mBuf(NULL) 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Destructor. Release resources. 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project_CompressedAsset::~_CompressedAsset(void) 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a chunk of compressed data inside a file. 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This currently just sets up some values and returns. On the first 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * read, we expand the entire file into a buffer and return data from it. 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 698ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Rootstatus_t _CompressedAsset::openChunk(int fd, off64_t offset, 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int compressionMethod, size_t uncompressedLen, size_t compressedLen) 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mFd < 0); // no re-open 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mMap == NULL); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(fd >= 0); 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(offset >= 0); 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(compressedLen > 0); 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (compressionMethod != ZipFileRO::kCompressDeflated) { 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(false); 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStart = offset; 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompressedLen = compressedLen; 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUncompressedLen = uncompressedLen; 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mOffset == 0); 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFd = fd; 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mBuf == NULL); 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 719b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) { 720b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate mZipInflater = new StreamingZipInflater(mFd, offset, uncompressedLen, compressedLen); 721b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate } 722b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a chunk of compressed data in a mapped region. 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Nothing is expanded until the first read call. 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t _CompressedAsset::openChunk(FileMap* dataMap, int compressionMethod, 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t uncompressedLen) 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mFd < 0); // no re-open 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mMap == NULL); 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(dataMap != NULL); 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (compressionMethod != ZipFileRO::kCompressDeflated) { 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(false); 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMap = dataMap; 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStart = -1; // not used 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompressedLen = dataMap->getDataLength(); 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUncompressedLen = uncompressedLen; 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mOffset == 0); 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) { 750b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate mZipInflater = new StreamingZipInflater(dataMap, uncompressedLen); 751b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate } 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Read data from a chunk of compressed data. 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * [For now, that's just copying data out of a buffer.] 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t _CompressedAsset::read(void* buf, size_t count) 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t maxLen; 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t actual; 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mOffset >= 0 && mOffset <= mUncompressedLen); 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 767b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate /* If we're relying on a streaming inflater, go through that */ 768b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate if (mZipInflater) { 769b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate actual = mZipInflater->read(buf, count); 770b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate } else { 771b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate if (mBuf == NULL) { 772b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate if (getBuffer(false) == NULL) 773b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate return -1; 774b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate } 775b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate assert(mBuf != NULL); 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 777b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate /* adjust count if we're near EOF */ 778b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate maxLen = mUncompressedLen - mOffset; 779b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate if (count > maxLen) 780b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate count = maxLen; 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 782b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate if (!count) 783b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate return 0; 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 785b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate /* copy from buffer */ 786b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate //printf("comp buf read\n"); 787b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate memcpy(buf, (char*)mBuf + mOffset, count); 788b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate actual = count; 789b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate } 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOffset += actual; 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return actual; 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Handle a seek request. 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If we're working in a streaming mode, this is going to be fairly 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * expensive, because it requires plowing through a bunch of compressed 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data. 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 802ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Rootoff64_t _CompressedAsset::seek(off64_t offset, int whence) 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 804ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root off64_t newPosn; 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute new position within chunk 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newPosn = handleSeek(offset, whence, mOffset, mUncompressedLen); 808ddb76c4644756b31be948d70aaa8ee541dd94999Kenny Root if (newPosn == (off64_t) -1) 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return newPosn; 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 811b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate if (mZipInflater) { 812b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate mZipInflater->seekAbsolute(newPosn); 813b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate } 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOffset = newPosn; 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mOffset; 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Close the asset. 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid _CompressedAsset::close(void) 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMap != NULL) { 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMap->release(); 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMap = NULL; 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 827b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate 828b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate delete[] mBuf; 829b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate mBuf = NULL; 830b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate 831b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate delete mZipInflater; 832b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate mZipInflater = NULL; 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFd > 0) { 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ::close(mFd); 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFd = -1; 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Get a pointer to a read-only buffer of data. 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The first time this is called, we expand the compressed data into a 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * buffer. 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 846afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamathconst void* _CompressedAsset::getBuffer(bool) 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char* buf = NULL; 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBuf != NULL) 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBuf; 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Allocate a buffer and read the file into it. 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf = new unsigned char[mUncompressedLen]; 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (buf == NULL) { 8588564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("alloc %ld bytes failed\n", (long) mUncompressedLen); 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMap != NULL) { 863afd31e08299008fdc5c2813f21b2573f29dc53dfNarayan Kamath if (!ZipUtils::inflateToBuffer(mMap->getDataPtr(), buf, 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUncompressedLen, mCompressedLen)) 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mFd >= 0); 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Seek to the start of the compressed data. 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lseek(mFd, mStart, SEEK_SET) != mStart) 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Expand the data into it. 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!ZipUtils::inflateToBuffer(mFd, buf, mUncompressedLen, 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompressedLen)) 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 883b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate /* 884b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate * Success - now that we have the full asset in RAM we 885b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate * no longer need the streaming inflater 886b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate */ 887b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate delete mZipInflater; 888b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate mZipInflater = NULL; 889b100cbf178e91d6652ebbad3ed36684cacb9d10eChristopher Tate 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBuf = buf; 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf = NULL; 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete[] buf; 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBuf; 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 898