diff options
author | 2010-07-26 11:24:18 -0700 | |
---|---|---|
committer | 2010-07-28 15:33:28 -0700 | |
commit | b100cbf178e91d6652ebbad3ed36684cacb9d10e (patch) | |
tree | acb386c8adee2d0390193fc631f841f8d76ea5d7 /libs/utils/Asset.cpp | |
parent | 0c39b6c65bcb96ed6438c7d792a67708409d8f0f (diff) |
Support streaming of compressed assets > 1 megabyte
Compressed assets larger than one megabyte are now decompressed on demand
rather than being decompressed in their entirety and held in memory. Reading
the data in order is relatively efficient, as is seeking forward in the stream.
Seeking backwards is supported, but requires reprocessing the compressed data
from the beginning, so is very inefficient.
In addition, the size limit on compressed assets has been eliminated.
Change-Id: I6e68247957e6c53e7e8ba70d12764695f1723bad
Diffstat (limited to 'libs/utils/Asset.cpp')
-rw-r--r-- | libs/utils/Asset.cpp | 74 |
1 files changed, 45 insertions, 29 deletions
diff --git a/libs/utils/Asset.cpp b/libs/utils/Asset.cpp index 42951237d627..cef7db492e55 100644 --- a/libs/utils/Asset.cpp +++ b/libs/utils/Asset.cpp @@ -24,6 +24,7 @@ #include <utils/Asset.h> #include <utils/Atomic.h> #include <utils/FileMap.h> +#include <utils/StreamingZipInflater.h> #include <utils/ZipUtils.h> #include <utils/ZipFileRO.h> #include <utils/Log.h> @@ -659,7 +660,7 @@ const void* _FileAsset::ensureAlignment(FileMap* map) */ _CompressedAsset::_CompressedAsset(void) : mStart(0), mCompressedLen(0), mUncompressedLen(0), mOffset(0), - mMap(NULL), mFd(-1), mBuf(NULL) + mMap(NULL), mFd(-1), mZipInflater(NULL), mBuf(NULL) { } @@ -698,6 +699,10 @@ status_t _CompressedAsset::openChunk(int fd, off_t offset, mFd = fd; assert(mBuf == NULL); + if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) { + mZipInflater = new StreamingZipInflater(mFd, offset, uncompressedLen, compressedLen); + } + return NO_ERROR; } @@ -724,6 +729,9 @@ status_t _CompressedAsset::openChunk(FileMap* dataMap, int compressionMethod, mUncompressedLen = uncompressedLen; assert(mOffset == 0); + if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) { + mZipInflater = new StreamingZipInflater(dataMap, uncompressedLen); + } return NO_ERROR; } @@ -739,26 +747,29 @@ ssize_t _CompressedAsset::read(void* buf, size_t count) assert(mOffset >= 0 && mOffset <= mUncompressedLen); - // TODO: if mAccessMode == ACCESS_STREAMING, use zlib more cleverly + /* If we're relying on a streaming inflater, go through that */ + if (mZipInflater) { + actual = mZipInflater->read(buf, count); + } else { + if (mBuf == NULL) { + if (getBuffer(false) == NULL) + return -1; + } + assert(mBuf != NULL); - if (mBuf == NULL) { - if (getBuffer(false) == NULL) - return -1; - } - assert(mBuf != NULL); + /* adjust count if we're near EOF */ + maxLen = mUncompressedLen - mOffset; + if (count > maxLen) + count = maxLen; - /* adjust count if we're near EOF */ - maxLen = mUncompressedLen - mOffset; - if (count > maxLen) - count = maxLen; + if (!count) + return 0; - if (!count) - return 0; - - /* copy from buffer */ - //printf("comp buf read\n"); - memcpy(buf, (char*)mBuf + mOffset, count); - actual = count; + /* copy from buffer */ + //printf("comp buf read\n"); + memcpy(buf, (char*)mBuf + mOffset, count); + actual = count; + } mOffset += actual; return actual; @@ -780,6 +791,9 @@ off_t _CompressedAsset::seek(off_t offset, int whence) if (newPosn == (off_t) -1) return newPosn; + if (mZipInflater) { + mZipInflater->seekAbsolute(newPosn); + } mOffset = newPosn; return mOffset; } @@ -793,10 +807,12 @@ void _CompressedAsset::close(void) mMap->release(); mMap = NULL; } - if (mBuf != NULL) { - delete[] mBuf; - mBuf = NULL; - } + + delete[] mBuf; + mBuf = NULL; + + delete mZipInflater; + mZipInflater = NULL; if (mFd > 0) { ::close(mFd); @@ -817,12 +833,6 @@ const void* _CompressedAsset::getBuffer(bool wordAligned) if (mBuf != NULL) return mBuf; - if (mUncompressedLen > UNCOMPRESS_DATA_MAX) { - LOGD("Data exceeds UNCOMPRESS_DATA_MAX (%ld vs %d)\n", - (long) mUncompressedLen, UNCOMPRESS_DATA_MAX); - goto bail; - } - /* * Allocate a buffer and read the file into it. */ @@ -853,7 +863,13 @@ const void* _CompressedAsset::getBuffer(bool wordAligned) goto bail; } - /* success! */ + /* + * Success - now that we have the full asset in RAM we + * no longer need the streaming inflater + */ + delete mZipInflater; + mZipInflater = NULL; + mBuf = buf; buf = NULL; |