summaryrefslogtreecommitdiffstats
path: root/libs/utils/StreamingZipInflater.cpp
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2012-02-20 16:58:20 -0800
committerMathias Agopian <mathias@google.com>2012-02-20 22:38:43 -0800
commit83c64e6b624a876436d2ef5d2f173b10407e27b4 (patch)
treec4effc3260ab399e8fdae23baf06b076cd87a604 /libs/utils/StreamingZipInflater.cpp
parent94d0024557f415b8463f085c9784a3e1d02b58c6 (diff)
downloadframeworks_base-83c64e6b624a876436d2ef5d2f173b10407e27b4.zip
frameworks_base-83c64e6b624a876436d2ef5d2f173b10407e27b4.tar.gz
frameworks_base-83c64e6b624a876436d2ef5d2f173b10407e27b4.tar.bz2
frameworks/base refactoring
create the new libandroidfw from parts of libui and libutils Change-Id: I1584995616fff5d527a2aba63921b682a6194d58
Diffstat (limited to 'libs/utils/StreamingZipInflater.cpp')
-rw-r--r--libs/utils/StreamingZipInflater.cpp226
1 files changed, 0 insertions, 226 deletions
diff --git a/libs/utils/StreamingZipInflater.cpp b/libs/utils/StreamingZipInflater.cpp
deleted file mode 100644
index d3fb98d..0000000
--- a/libs/utils/StreamingZipInflater.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "szipinf"
-#include <utils/Log.h>
-
-#include <androidfw/StreamingZipInflater.h>
-#include <utils/FileMap.h>
-#include <string.h>
-#include <stddef.h>
-#include <assert.h>
-
-static inline size_t min_of(size_t a, size_t b) { return (a < b) ? a : b; }
-
-using namespace android;
-
-/*
- * Streaming access to compressed asset data in an open fd
- */
-StreamingZipInflater::StreamingZipInflater(int fd, off64_t compDataStart,
- size_t uncompSize, size_t compSize) {
- mFd = fd;
- mDataMap = NULL;
- mInFileStart = compDataStart;
- mOutTotalSize = uncompSize;
- mInTotalSize = compSize;
-
- mInBufSize = StreamingZipInflater::INPUT_CHUNK_SIZE;
- mInBuf = new uint8_t[mInBufSize];
-
- mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;
- mOutBuf = new uint8_t[mOutBufSize];
-
- initInflateState();
-}
-
-/*
- * Streaming access to compressed data held in an mmapped region of memory
- */
-StreamingZipInflater::StreamingZipInflater(FileMap* dataMap, size_t uncompSize) {
- mFd = -1;
- mDataMap = dataMap;
- mOutTotalSize = uncompSize;
- mInTotalSize = dataMap->getDataLength();
-
- mInBuf = (uint8_t*) dataMap->getDataPtr();
- mInBufSize = mInTotalSize;
-
- mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;
- mOutBuf = new uint8_t[mOutBufSize];
-
- initInflateState();
-}
-
-StreamingZipInflater::~StreamingZipInflater() {
- // tear down the in-flight zip state just in case
- ::inflateEnd(&mInflateState);
-
- if (mDataMap == NULL) {
- delete [] mInBuf;
- }
- delete [] mOutBuf;
-}
-
-void StreamingZipInflater::initInflateState() {
- ALOGV("Initializing inflate state");
-
- memset(&mInflateState, 0, sizeof(mInflateState));
- mInflateState.zalloc = Z_NULL;
- mInflateState.zfree = Z_NULL;
- mInflateState.opaque = Z_NULL;
- mInflateState.next_in = (Bytef*)mInBuf;
- mInflateState.next_out = (Bytef*) mOutBuf;
- mInflateState.avail_out = mOutBufSize;
- mInflateState.data_type = Z_UNKNOWN;
-
- mOutLastDecoded = mOutDeliverable = mOutCurPosition = 0;
- mInNextChunkOffset = 0;
- mStreamNeedsInit = true;
-
- if (mDataMap == NULL) {
- ::lseek(mFd, mInFileStart, SEEK_SET);
- mInflateState.avail_in = 0; // set when a chunk is read in
- } else {
- mInflateState.avail_in = mInBufSize;
- }
-}
-
-/*
- * Basic approach:
- *
- * 1. If we have undelivered uncompressed data, send it. At this point
- * either we've satisfied the request, or we've exhausted the available
- * output data in mOutBuf.
- *
- * 2. While we haven't sent enough data to satisfy the request:
- * 0. if the request is for more data than exists, bail.
- * a. if there is no input data to decode, read some into the input buffer
- * and readjust the z_stream input pointers
- * b. point the output to the start of the output buffer and decode what we can
- * c. deliver whatever output data we can
- */
-ssize_t StreamingZipInflater::read(void* outBuf, size_t count) {
- uint8_t* dest = (uint8_t*) outBuf;
- size_t bytesRead = 0;
- size_t toRead = min_of(count, size_t(mOutTotalSize - mOutCurPosition));
- while (toRead > 0) {
- // First, write from whatever we already have decoded and ready to go
- size_t deliverable = min_of(toRead, mOutLastDecoded - mOutDeliverable);
- if (deliverable > 0) {
- if (outBuf != NULL) memcpy(dest, mOutBuf + mOutDeliverable, deliverable);
- mOutDeliverable += deliverable;
- mOutCurPosition += deliverable;
- dest += deliverable;
- bytesRead += deliverable;
- toRead -= deliverable;
- }
-
- // need more data? time to decode some.
- if (toRead > 0) {
- // if we don't have any data to decode, read some in. If we're working
- // from mmapped data this won't happen, because the clipping to total size
- // will prevent reading off the end of the mapped input chunk.
- if (mInflateState.avail_in == 0) {
- int err = readNextChunk();
- if (err < 0) {
- ALOGE("Unable to access asset data: %d", err);
- if (!mStreamNeedsInit) {
- ::inflateEnd(&mInflateState);
- initInflateState();
- }
- return -1;
- }
- }
- // we know we've drained whatever is in the out buffer now, so just
- // start from scratch there, reading all the input we have at present.
- mInflateState.next_out = (Bytef*) mOutBuf;
- mInflateState.avail_out = mOutBufSize;
-
- /*
- ALOGV("Inflating to outbuf: avail_in=%u avail_out=%u next_in=%p next_out=%p",
- mInflateState.avail_in, mInflateState.avail_out,
- mInflateState.next_in, mInflateState.next_out);
- */
- int result = Z_OK;
- if (mStreamNeedsInit) {
- ALOGV("Initializing zlib to inflate");
- result = inflateInit2(&mInflateState, -MAX_WBITS);
- mStreamNeedsInit = false;
- }
- if (result == Z_OK) result = ::inflate(&mInflateState, Z_SYNC_FLUSH);
- if (result < 0) {
- // Whoops, inflation failed
- ALOGE("Error inflating asset: %d", result);
- ::inflateEnd(&mInflateState);
- initInflateState();
- return -1;
- } else {
- if (result == Z_STREAM_END) {
- // we know we have to have reached the target size here and will
- // not try to read any further, so just wind things up.
- ::inflateEnd(&mInflateState);
- }
-
- // Note how much data we got, and off we go
- mOutDeliverable = 0;
- mOutLastDecoded = mOutBufSize - mInflateState.avail_out;
- }
- }
- }
- return bytesRead;
-}
-
-int StreamingZipInflater::readNextChunk() {
- assert(mDataMap == NULL);
-
- if (mInNextChunkOffset < mInTotalSize) {
- size_t toRead = min_of(mInBufSize, mInTotalSize - mInNextChunkOffset);
- if (toRead > 0) {
- ssize_t didRead = ::read(mFd, mInBuf, toRead);
- //ALOGV("Reading input chunk, size %08x didread %08x", toRead, didRead);
- if (didRead < 0) {
- // TODO: error
- ALOGE("Error reading asset data");
- return didRead;
- } else {
- mInNextChunkOffset += didRead;
- mInflateState.next_in = (Bytef*) mInBuf;
- mInflateState.avail_in = didRead;
- }
- }
- }
- return 0;
-}
-
-// seeking backwards requires uncompressing fom the beginning, so is very
-// expensive. seeking forwards only requires uncompressing from the current
-// position to the destination.
-off64_t StreamingZipInflater::seekAbsolute(off64_t absoluteInputPosition) {
- if (absoluteInputPosition < mOutCurPosition) {
- // rewind and reprocess the data from the beginning
- if (!mStreamNeedsInit) {
- ::inflateEnd(&mInflateState);
- }
- initInflateState();
- read(NULL, absoluteInputPosition);
- } else if (absoluteInputPosition > mOutCurPosition) {
- read(NULL, absoluteInputPosition - mOutCurPosition);
- }
- // else if the target position *is* our current position, do nothing
- return absoluteInputPosition;
-}