diff options
Diffstat (limited to 'libs/androidfw/Asset.cpp')
-rw-r--r-- | libs/androidfw/Asset.cpp | 174 |
1 files changed, 100 insertions, 74 deletions
diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp index 4fbe4a3efbdd..cd30c184d5a4 100644 --- a/libs/androidfw/Asset.cpp +++ b/libs/androidfw/Asset.cpp @@ -298,18 +298,34 @@ Asset::Asset(void) /* * Create a new Asset from a memory mapping. */ -/*static*/ std::unique_ptr<Asset> Asset::createFromUncompressedMap(incfs::IncFsFileMap&& dataMap, - AccessMode mode, - base::unique_fd fd) +/*static*/ Asset* Asset::createFromUncompressedMap(FileMap* dataMap, AccessMode mode) { - auto pAsset = util::make_unique<_FileAsset>(); + _FileAsset* pAsset; + status_t result; + + pAsset = new _FileAsset; + result = pAsset->openChunk(dataMap, base::unique_fd(-1)); + if (result != NO_ERROR) { + delete pAsset; + return NULL; + } + + pAsset->mAccessMode = mode; + return pAsset; +} - status_t result = pAsset->openChunk(std::move(dataMap), std::move(fd)); +/*static*/ std::unique_ptr<Asset> Asset::createFromUncompressedMap(std::unique_ptr<FileMap> dataMap, + base::unique_fd fd, AccessMode mode) +{ + std::unique_ptr<_FileAsset> pAsset = util::make_unique<_FileAsset>(); + + status_t result = pAsset->openChunk(dataMap.get(), std::move(fd)); if (result != NO_ERROR) { return NULL; } // We succeeded, so relinquish control of dataMap + (void) dataMap.release(); pAsset->mAccessMode = mode; return std::move(pAsset); } @@ -317,18 +333,35 @@ Asset::Asset(void) /* * Create a new Asset from compressed data in a memory mapping. */ -/*static*/ std::unique_ptr<Asset> Asset::createFromCompressedMap(incfs::IncFsFileMap&& dataMap, - size_t uncompressedLen, - AccessMode mode) +/*static*/ Asset* Asset::createFromCompressedMap(FileMap* dataMap, + size_t uncompressedLen, AccessMode mode) { - auto pAsset = util::make_unique<_CompressedAsset>(); + _CompressedAsset* pAsset; + status_t result; + + pAsset = new _CompressedAsset; + result = pAsset->openChunk(dataMap, uncompressedLen); + if (result != NO_ERROR) { + delete pAsset; + return NULL; + } - status_t result = pAsset->openChunk(std::move(dataMap), uncompressedLen); + pAsset->mAccessMode = mode; + return pAsset; +} + +/*static*/ std::unique_ptr<Asset> Asset::createFromCompressedMap(std::unique_ptr<FileMap> dataMap, + size_t uncompressedLen, AccessMode mode) +{ + std::unique_ptr<_CompressedAsset> pAsset = util::make_unique<_CompressedAsset>(); + + status_t result = pAsset->openChunk(dataMap.get(), uncompressedLen); if (result != NO_ERROR) { return NULL; } // We succeeded, so relinquish control of dataMap + (void) dataMap.release(); pAsset->mAccessMode = mode; return std::move(pAsset); } @@ -381,7 +414,7 @@ off64_t Asset::handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t m * Constructor. */ _FileAsset::_FileAsset(void) - : mStart(0), mLength(0), mOffset(0), mFp(NULL), mFileName(NULL), mFd(-1), mBuf(NULL) + : mStart(0), mLength(0), mOffset(0), mFp(NULL), mFileName(NULL), mFd(-1), mMap(NULL), mBuf(NULL) { // Register the Asset with the global list here after it is fully constructed and its // vtable pointer points to this concrete type. b/31113965 @@ -408,7 +441,7 @@ _FileAsset::~_FileAsset(void) status_t _FileAsset::openChunk(const char* fileName, int fd, off64_t offset, size_t length) { assert(mFp == NULL); // no reopen - assert(!mMap.has_value()); + assert(mMap == NULL); assert(fd >= 0); assert(offset >= 0); @@ -451,15 +484,15 @@ status_t _FileAsset::openChunk(const char* fileName, int fd, off64_t offset, siz /* * Create the chunk from the map. */ -status_t _FileAsset::openChunk(incfs::IncFsFileMap&& dataMap, base::unique_fd fd) +status_t _FileAsset::openChunk(FileMap* dataMap, base::unique_fd fd) { assert(mFp == NULL); // no reopen - assert(!mMap.has_value()); + assert(mMap == NULL); assert(dataMap != NULL); - mMap = std::move(dataMap); + mMap = dataMap; mStart = -1; // not used - mLength = mMap->length(); + mLength = dataMap->getDataLength(); mFd = std::move(fd); assert(mOffset == 0); @@ -495,15 +528,10 @@ ssize_t _FileAsset::read(void* buf, size_t count) if (!count) return 0; - if (mMap.has_value()) { + if (mMap != NULL) { /* copy from mapped area */ //printf("map read\n"); - const auto readPos = mMap->data().offset(mOffset).convert<char>(); - if (!readPos.verify(count)) { - return -1; - } - - memcpy(buf, readPos.unsafe_ptr(), count); + memcpy(buf, (char*)mMap->getDataPtr() + mOffset, count); actual = count; } else if (mBuf != NULL) { /* copy from buffer */ @@ -566,6 +594,10 @@ off64_t _FileAsset::seek(off64_t offset, int whence) */ void _FileAsset::close(void) { + if (mMap != NULL) { + delete mMap; + mMap = NULL; + } if (mBuf != NULL) { delete[] mBuf; mBuf = NULL; @@ -592,21 +624,16 @@ void _FileAsset::close(void) * level and we'd be using a different object, but we didn't, so we * deal with it here. */ -const void* _FileAsset::getBuffer(bool aligned) -{ - return getIncFsBuffer(aligned).unsafe_ptr(); -} - -incfs::map_ptr<void> _FileAsset::getIncFsBuffer(bool aligned) +const void* _FileAsset::getBuffer(bool wordAligned) { /* subsequent requests just use what we did previously */ if (mBuf != NULL) return mBuf; - if (mMap.has_value()) { - if (!aligned) { - return mMap->data(); + if (mMap != NULL) { + if (!wordAligned) { + return mMap->getDataPtr(); } - return ensureAlignment(*mMap); + return ensureAlignment(mMap); } assert(mFp != NULL); @@ -644,44 +671,47 @@ incfs::map_ptr<void> _FileAsset::getIncFsBuffer(bool aligned) mBuf = buf; return mBuf; } else { - incfs::IncFsFileMap map; - if (!map.Create(fileno(mFp), mStart, mLength, NULL /* file_name */ )) { + FileMap* map; + + map = new FileMap; + if (!map->create(NULL, fileno(mFp), mStart, mLength, true)) { + delete map; return NULL; } ALOGV(" getBuffer: mapped\n"); - mMap = std::move(map); - if (!aligned) { - return mMap->data(); + mMap = map; + if (!wordAligned) { + return mMap->getDataPtr(); } - return ensureAlignment(*mMap); + return ensureAlignment(mMap); } } int _FileAsset::openFileDescriptor(off64_t* outStart, off64_t* outLength) const { - if (mMap.has_value()) { + if (mMap != NULL) { if (mFd.ok()) { - *outStart = mMap->offset(); - *outLength = mMap->length(); - const int fd = dup(mFd); - if (fd < 0) { - ALOGE("Unable to dup fd (%d).", mFd.get()); - return -1; - } - lseek64(fd, 0, SEEK_SET); - return fd; + *outStart = mMap->getDataOffset(); + *outLength = mMap->getDataLength(); + const int fd = dup(mFd); + if (fd < 0) { + ALOGE("Unable to dup fd (%d).", mFd.get()); + return -1; + } + lseek64(fd, 0, SEEK_SET); + return fd; } - const char* fname = mMap->file_name(); + const char* fname = mMap->getFileName(); if (fname == NULL) { fname = mFileName; } if (fname == NULL) { return -1; } - *outStart = mMap->offset(); - *outLength = mMap->length(); + *outStart = mMap->getDataOffset(); + *outLength = mMap->getDataLength(); return open(fname, O_RDONLY | O_BINARY); } if (mFileName == NULL) { @@ -692,21 +722,16 @@ int _FileAsset::openFileDescriptor(off64_t* outStart, off64_t* outLength) const return open(mFileName, O_RDONLY | O_BINARY); } -incfs::map_ptr<void> _FileAsset::ensureAlignment(const incfs::IncFsFileMap& map) +const void* _FileAsset::ensureAlignment(FileMap* map) { - const auto data = map.data(); - if (util::IsFourByteAligned(data)) { + void* data = map->getDataPtr(); + if ((((size_t)data)&0x3) == 0) { // We can return this directly if it is aligned on a word // boundary. ALOGV("Returning aligned FileAsset %p (%s).", this, getAssetSource()); return data; } - - if (!data.convert<uint8_t>().verify(mLength)) { - return NULL; - } - // If not aligned on a word boundary, then we need to copy it into // our own buffer. ALOGV("Copying FileAsset %p (%s) to buffer size %d to make it aligned.", this, @@ -716,8 +741,7 @@ incfs::map_ptr<void> _FileAsset::ensureAlignment(const incfs::IncFsFileMap& map) ALOGE("alloc of %ld bytes failed\n", (long) mLength); return NULL; } - - memcpy(buf, data.unsafe_ptr(), mLength); + memcpy(buf, data, mLength); mBuf = buf; return buf; } @@ -733,7 +757,7 @@ incfs::map_ptr<void> _FileAsset::ensureAlignment(const incfs::IncFsFileMap& map) */ _CompressedAsset::_CompressedAsset(void) : mStart(0), mCompressedLen(0), mUncompressedLen(0), mOffset(0), - mFd(-1), mZipInflater(NULL), mBuf(NULL) + mMap(NULL), mFd(-1), mZipInflater(NULL), mBuf(NULL) { // Register the Asset with the global list here after it is fully constructed and its // vtable pointer points to this concrete type. b/31113965 @@ -762,7 +786,7 @@ status_t _CompressedAsset::openChunk(int fd, off64_t offset, int compressionMethod, size_t uncompressedLen, size_t compressedLen) { assert(mFd < 0); // no re-open - assert(!mMap.has_value()); + assert(mMap == NULL); assert(fd >= 0); assert(offset >= 0); assert(compressedLen > 0); @@ -791,20 +815,20 @@ status_t _CompressedAsset::openChunk(int fd, off64_t offset, * * Nothing is expanded until the first read call. */ -status_t _CompressedAsset::openChunk(incfs::IncFsFileMap&& dataMap, size_t uncompressedLen) +status_t _CompressedAsset::openChunk(FileMap* dataMap, size_t uncompressedLen) { assert(mFd < 0); // no re-open - assert(!mMap.has_value()); + assert(mMap == NULL); assert(dataMap != NULL); - mMap = std::move(dataMap); + mMap = dataMap; mStart = -1; // not used - mCompressedLen = mMap->length(); + mCompressedLen = dataMap->getDataLength(); mUncompressedLen = uncompressedLen; assert(mOffset == 0); if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) { - mZipInflater = new StreamingZipInflater(&(*mMap), uncompressedLen); + mZipInflater = new StreamingZipInflater(dataMap, uncompressedLen); } return NO_ERROR; } @@ -877,6 +901,11 @@ off64_t _CompressedAsset::seek(off64_t offset, int whence) */ void _CompressedAsset::close(void) { + if (mMap != NULL) { + delete mMap; + mMap = NULL; + } + delete[] mBuf; mBuf = NULL; @@ -911,8 +940,8 @@ const void* _CompressedAsset::getBuffer(bool) goto bail; } - if (mMap.has_value()) { - if (!ZipUtils::inflateToBuffer(mMap->data(), buf, + if (mMap != NULL) { + if (!ZipUtils::inflateToBuffer(mMap->getDataPtr(), buf, mUncompressedLen, mCompressedLen)) goto bail; } else { @@ -947,6 +976,3 @@ bail: return mBuf; } -incfs::map_ptr<void> _CompressedAsset::getIncFsBuffer(bool aligned) { - return incfs::map_ptr<void>(getBuffer(aligned)); -} |