116c4d154dca43c662571129af31b27433b919a32Adam Lesinski/*
216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Copyright (C) 2010 The Android Open Source Project
316c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * you may not use this file except in compliance with the License.
616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * You may obtain a copy of the License at
716c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
816c4d154dca43c662571129af31b27433b919a32Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
916c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
1016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Unless required by applicable law or agreed to in writing, software
1116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
1216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * See the License for the specific language governing permissions and
1416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * limitations under the License.
1516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */
1616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
1716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifndef __LIBS_STREAMINGZIPINFLATER_H
1816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define __LIBS_STREAMINGZIPINFLATER_H
1916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
2016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <unistd.h>
2116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <inttypes.h>
2216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <zlib.h>
2316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
2416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/Compat.h>
2516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
2616c4d154dca43c662571129af31b27433b919a32Adam Lesinskinamespace android {
2716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
2816c4d154dca43c662571129af31b27433b919a32Adam Lesinskiclass StreamingZipInflater {
2916c4d154dca43c662571129af31b27433b919a32Adam Lesinskipublic:
3016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    static const size_t INPUT_CHUNK_SIZE = 64 * 1024;
3116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    static const size_t OUTPUT_CHUNK_SIZE = 64 * 1024;
3216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // Flavor that pages in the compressed data from a fd
3416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    StreamingZipInflater(int fd, off64_t compDataStart, size_t uncompSize, size_t compSize);
3516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // Flavor that gets the compressed data from an in-memory buffer
3716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    StreamingZipInflater(class FileMap* dataMap, size_t uncompSize);
3816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ~StreamingZipInflater();
4016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
4116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // read 'count' bytes of uncompressed data from the current position.  outBuf may
4216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // be NULL, in which case the data is consumed and discarded.
4316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ssize_t read(void* outBuf, size_t count);
4416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
4516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // seeking backwards requires uncompressing fom the beginning, so is very
4616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // expensive.  seeking forwards only requires uncompressing from the current
4716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // position to the destination.
4816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    off64_t seekAbsolute(off64_t absoluteInputPosition);
4916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
5016c4d154dca43c662571129af31b27433b919a32Adam Lesinskiprivate:
5116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    void initInflateState();
5216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    int readNextChunk();
5316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
5416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // where to find the uncompressed data
5516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    int mFd;
5616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    off64_t mInFileStart;         // where the compressed data lives in the file
5716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    class FileMap* mDataMap;
5816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
5916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    z_stream mInflateState;
6016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    bool mStreamNeedsInit;
6116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
6216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // output invariants for this asset
6316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    uint8_t* mOutBuf;           // output buf for decompressed bytes
6416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    size_t mOutBufSize;         // allocated size of mOutBuf
6516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    size_t mOutTotalSize;       // total uncompressed size of the blob
6616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
6716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // current output state bookkeeping
6816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    off64_t mOutCurPosition;      // current position in total offset
6916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    size_t mOutLastDecoded;     // last decoded byte + 1 in mOutbuf
7016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    size_t mOutDeliverable;     // next undelivered byte of decoded output in mOutBuf
7116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
7216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // input invariants
7316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    uint8_t* mInBuf;
7416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    size_t mInBufSize;          // allocated size of mInBuf;
7516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    size_t mInTotalSize;        // total size of compressed data for this blob
7616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
7716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // input state bookkeeping
7816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    size_t mInNextChunkOffset;  // offset from start of blob at which the next input chunk lies
7916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // the z_stream contains state about input block consumption
8016c4d154dca43c662571129af31b27433b919a32Adam Lesinski};
8116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8216c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
8316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif
85