/*
 * Copyright (C) 2006 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.
 */

//
// Access to Zip archives.
//

#define LOG_TAG "zip"

#include <utils/Log.h>
#include <ziparchive/zip_archive.h>

#include "ZipFile.h"

#include <zlib.h>

#include "zopfli/deflate.h"

#include <memory.h>
#include <sys/stat.h>
#include <errno.h>
#include <assert.h>
#include <inttypes.h>

_Static_assert(sizeof(off_t) == 8, "off_t too small");

namespace android {

/*
 * Some environments require the "b", some choke on it.
 */
#define FILE_OPEN_RO        "rb"
#define FILE_OPEN_RW        "r+b"
#define FILE_OPEN_RW_CREATE "w+b"

/* should live somewhere else? */
static status_t errnoToStatus(int err)
{
    if (err == ENOENT)
        return NAME_NOT_FOUND;
    else if (err == EACCES)
        return PERMISSION_DENIED;
    else
        return UNKNOWN_ERROR;
}

/*
 * Open a file and parse its guts.
 */
status_t ZipFile::open(const char* zipFileName, int flags)
{
    bool newArchive = false;

    assert(mZipFp == NULL);     // no reopen

    if ((flags & kOpenTruncate))
        flags |= kOpenCreate;           // trunc implies create

    if ((flags & kOpenReadOnly) && (flags & kOpenReadWrite))
        return INVALID_OPERATION;       // not both
    if (!((flags & kOpenReadOnly) || (flags & kOpenReadWrite)))
        return INVALID_OPERATION;       // not neither
    if ((flags & kOpenCreate) && !(flags & kOpenReadWrite))
        return INVALID_OPERATION;       // create requires write

    if (flags & kOpenTruncate) {
        newArchive = true;
    } else {
        newArchive = (access(zipFileName, F_OK) != 0);
        if (!(flags & kOpenCreate) && newArchive) {
            /* not creating, must already exist */
            ALOGD("File %s does not exist", zipFileName);
            return NAME_NOT_FOUND;
        }
    }

    /* open the file */
    const char* openflags;
    if (flags & kOpenReadWrite) {
        if (newArchive)
            openflags = FILE_OPEN_RW_CREATE;
        else
            openflags = FILE_OPEN_RW;
    } else {
        openflags = FILE_OPEN_RO;
    }
    mZipFp = fopen(zipFileName, openflags);
    if (mZipFp == NULL) {
        int err = errno;
        ALOGD("fopen failed: %d\n", err);
        return errnoToStatus(err);
    }

    status_t result;
    if (!newArchive) {
        /*
         * Load the central directory.  If that fails, then this probably
         * isn't a Zip archive.
         */
        result = readCentralDir();
    } else {
        /*
         * Newly-created.  The EndOfCentralDir constructor actually
         * sets everything to be the way we want it (all zeroes).  We
         * set mNeedCDRewrite so that we create *something* if the
         * caller doesn't add any files.  (We could also just unlink
         * the file if it's brand new and nothing was added, but that's
         * probably doing more than we really should -- the user might
         * have a need for empty zip files.)
         */
        mNeedCDRewrite = true;
        result = OK;
    }

    if (flags & kOpenReadOnly)
        mReadOnly = true;
    else
        assert(!mReadOnly);

    return result;
}

/*
 * Return the Nth entry in the archive.
 */
ZipEntry* ZipFile::getEntryByIndex(int idx) const
{
    if (idx < 0 || idx >= (int) mEntries.size())
        return NULL;

    return mEntries[idx];
}

/*
 * Find an entry by name.
 */
ZipEntry* ZipFile::getEntryByName(const char* fileName) const
{
    /*
     * Do a stupid linear string-compare search.
     *
     * There are various ways to speed this up, especially since it's rare
     * to intermingle changes to the archive with "get by name" calls.  We
     * don't want to sort the mEntries vector itself, however, because
     * it's used to recreate the Central Directory.
     *
     * (Hash table works, parallel list of pointers in sorted order is good.)
     */
    int idx;

    for (idx = mEntries.size()-1; idx >= 0; idx--) {
        ZipEntry* pEntry = mEntries[idx];
        if (!pEntry->getDeleted() &&
            strcmp(fileName, pEntry->getFileName()) == 0)
        {
            return pEntry;
        }
    }

    return NULL;
}

/*
 * Empty the mEntries vector.
 */
void ZipFile::discardEntries(void)
{
    int count = mEntries.size();

    while (--count >= 0)
        delete mEntries[count];

    mEntries.clear();
}


/*
 * Find the central directory and read the contents.
 *
 * The fun thing about ZIP archives is that they may or may not be
 * readable from start to end.  In some cases, notably for archives
 * that were written to stdout, the only length information is in the
 * central directory at the end of the file.
 *
 * Of course, the central directory can be followed by a variable-length
 * comment field, so we have to scan through it backwards.  The comment
 * is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff
 * itself, plus apparently sometimes people throw random junk on the end
 * just for the fun of it.
 *
 * This is all a little wobbly.  If the wrong value ends up in the EOCD
 * area, we're hosed.  This appears to be the way that everbody handles
 * it though, so we're in pretty good company if this fails.
 */
status_t ZipFile::readCentralDir(void)
{
    fseeko(mZipFp, 0, SEEK_END);
    off_t fileLength = ftello(mZipFp);
    rewind(mZipFp);

    /* too small to be a ZIP archive? */
    if (fileLength < EndOfCentralDir::kEOCDLen) {
        ALOGD("Length is %lld -- too small\n", (long long) fileLength);
        return INVALID_OPERATION;
    }

    off_t seekStart;
    size_t readAmount;
    if (fileLength > EndOfCentralDir::kMaxEOCDSearch) {
        seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch;
        readAmount = EndOfCentralDir::kMaxEOCDSearch;
    } else {
        seekStart = 0;
        readAmount = fileLength;
    }
    if (fseeko(mZipFp, seekStart, SEEK_SET) != 0) {
        ALOGD("Failure seeking to end of zip at %lld", (long long) seekStart);
        return UNKNOWN_ERROR;
    }

    /* read the last part of the file into the buffer */
    uint8_t buf[EndOfCentralDir::kMaxEOCDSearch];
    if (fread(buf, 1, readAmount, mZipFp) != readAmount) {
        if (feof(mZipFp)) {
            ALOGW("fread %zu bytes failed, unexpected EOF", readAmount);
        } else {
            ALOGW("fread %zu bytes failed, %s", readAmount, strerror(errno));
        }
        return UNKNOWN_ERROR;
    }

    /* find the end-of-central-dir magic */
    int i;
    for (i = readAmount - 4; i >= 0; i--) {
        if (buf[i] == 0x50 &&
            ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature)
        {
            ALOGV("+++ Found EOCD at buf+%d\n", i);
            break;
        }
    }
    if (i < 0) {
        ALOGD("EOCD not found, not Zip\n");
        return INVALID_OPERATION;
    }

    /* extract eocd values */
    status_t result = mEOCD.readBuf(buf + i, readAmount - i);
    if (result != OK) {
        ALOGD("Failure reading %zu bytes of EOCD values", readAmount - i);
        return result;
    }
    //mEOCD.dump();

    if (mEOCD.mDiskNumber != 0 || mEOCD.mDiskWithCentralDir != 0 ||
        mEOCD.mNumEntries != mEOCD.mTotalNumEntries)
    {
        ALOGD("Archive spanning not supported\n");
        return INVALID_OPERATION;
    }

    /*
     * So far so good.  "mCentralDirSize" is the size in bytes of the
     * central directory, so we can just seek back that far to find it.
     * We can also seek forward mCentralDirOffset bytes from the
     * start of the file.
     *
     * We're not guaranteed to have the rest of the central dir in the
     * buffer, nor are we guaranteed that the central dir will have any
     * sort of convenient size.  We need to skip to the start of it and
     * read the header, then the other goodies.
     *
     * The only thing we really need right now is the file comment, which
     * we're hoping to preserve.
     */
    if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
        ALOGD("Failure seeking to central dir offset %" PRIu32 "\n",
             mEOCD.mCentralDirOffset);
        return UNKNOWN_ERROR;
    }

    /*
     * Loop through and read the central dir entries.
     */
    ALOGV("Scanning %" PRIu16 " entries...\n", mEOCD.mTotalNumEntries);
    int entry;
    for (entry = 0; entry < mEOCD.mTotalNumEntries; entry++) {
        ZipEntry* pEntry = new ZipEntry;

        result = pEntry->initFromCDE(mZipFp);
        if (result != OK) {
            ALOGD("initFromCDE failed\n");
            delete pEntry;
            return result;
        }

        mEntries.add(pEntry);
    }


    /*
     * If all went well, we should now be back at the EOCD.
     */
    {
        uint8_t checkBuf[4];
        if (fread(checkBuf, 1, 4, mZipFp) != 4) {
            if (feof(mZipFp)) {
                ALOGW("fread EOCD failed, unexpected EOF");
            } else {
                ALOGW("fread EOCD failed, %s", strerror(errno));
            }
            return INVALID_OPERATION;
        }
        if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) {
            ALOGD("EOCD read check failed\n");
            return UNKNOWN_ERROR;
        }
        ALOGV("+++ EOCD read check passed\n");
    }

    return OK;
}


/*
 * Add a new file to the archive.
 *
 * This requires creating and populating a ZipEntry structure, and copying
 * the data into the file at the appropriate position.  The "appropriate
 * position" is the current location of the central directory, which we
 * casually overwrite (we can put it back later).
 *
 * If we were concerned about safety, we would want to make all changes
 * in a temp file and then overwrite the original after everything was
 * safely written.  Not really a concern for us.
 */
status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size,
    const char* storageName, int compressionMethod, ZipEntry** ppEntry)
{
    ZipEntry* pEntry = NULL;
    status_t result = OK;
    off_t lfhPosn, startPosn, endPosn, uncompressedLen;
    uint32_t crc = 0;
    time_t modWhen;

    if (mReadOnly)
        return INVALID_OPERATION;

    assert(compressionMethod == ZipEntry::kCompressDeflated ||
           compressionMethod == ZipEntry::kCompressStored);

    /* make sure we're in a reasonable state */
    assert(mZipFp != NULL);
    assert(mEntries.size() == mEOCD.mTotalNumEntries);

    /* make sure it doesn't already exist */
    if (getEntryByName(storageName) != NULL)
        return ALREADY_EXISTS;

    FILE* inputFp = NULL;
    if (!data) {
        inputFp = fopen(fileName, FILE_OPEN_RO);
        if (inputFp == NULL)
            return errnoToStatus(errno);
    }

    if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
        result = UNKNOWN_ERROR;
        goto bail;
    }

    pEntry = new ZipEntry;
    pEntry->initNew(storageName, NULL);

    /*
     * From here on out, failures are more interesting.
     */
    mNeedCDRewrite = true;

    /*
     * Write the LFH, even though it's still mostly blank.  We need it
     * as a place-holder.  In theory the LFH isn't necessary, but in
     * practice some utilities demand it.
     */
    lfhPosn = ftello(mZipFp);
    pEntry->mLFH.write(mZipFp);
    startPosn = ftello(mZipFp);

    /*
     * Copy the data in, possibly compressing it as we go.
     */
    if (compressionMethod == ZipEntry::kCompressDeflated) {
        bool failed = false;
        result = compressFpToFp(mZipFp, inputFp, data, size, &crc);
        if (result != OK) {
            ALOGD("compression failed, storing\n");
            failed = true;
        } else {
            /*
             * Make sure it has compressed "enough".  This probably ought
             * to be set through an API call, but I don't expect our
             * criteria to change over time.
             */
            off_t src = inputFp ? ftello(inputFp) : size;
            off_t dst = ftello(mZipFp) - startPosn;
            if (dst + (dst / 10) > src) {
                ALOGD("insufficient compression (src=%lld dst=%lld), storing\n",
                    (long long) src, (long long) dst);
                failed = true;
            }
        }

        if (failed) {
            compressionMethod = ZipEntry::kCompressStored;
            if (inputFp) rewind(inputFp);
            fseeko(mZipFp, startPosn, SEEK_SET);
            /* fall through to kCompressStored case */
        }
    }
    /* handle "no compression" request, or failed compression from above */
    if (compressionMethod == ZipEntry::kCompressStored) {
        if (inputFp) {
            result = copyFpToFp(mZipFp, inputFp, &crc);
        } else {
            result = copyDataToFp(mZipFp, data, size, &crc);
        }
        if (result != OK) {
            // don't need to truncate; happens in CDE rewrite
            ALOGD("failed copying data in\n");
            goto bail;
        }
    }

    // currently seeked to end of file
    uncompressedLen = inputFp ? ftello(inputFp) : size;

    /*
     * We could write the "Data Descriptor", but there doesn't seem to
     * be any point since we're going to go back and write the LFH.
     *
     * Update file offsets.
     */
    endPosn = ftello(mZipFp);            // seeked to end of compressed data

    /*
     * Success!  Fill out new values.
     */
    pEntry->setDataInfo(uncompressedLen, endPosn - startPosn, crc,
        compressionMethod);
    modWhen = getModTime(inputFp ? fileno(inputFp) : fileno(mZipFp));
    pEntry->setModWhen(modWhen);
    pEntry->setLFHOffset(lfhPosn);
    mEOCD.mNumEntries++;
    mEOCD.mTotalNumEntries++;
    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
    mEOCD.mCentralDirOffset = endPosn;

    /*
     * Go back and write the LFH.
     */
    if (fseeko(mZipFp, lfhPosn, SEEK_SET) != 0) {
        result = UNKNOWN_ERROR;
        goto bail;
    }
    pEntry->mLFH.write(mZipFp);

    /*
     * Add pEntry to the list.
     */
    mEntries.add(pEntry);
    if (ppEntry != NULL)
        *ppEntry = pEntry;
    pEntry = NULL;

bail:
    if (inputFp != NULL)
        fclose(inputFp);
    delete pEntry;
    return result;
}

/*
 * Based on the current position in the output zip, assess where the entry
 * payload will end up if written as-is. If alignment is not satisfactory,
 * add some padding in the extra field.
 *
 */
status_t ZipFile::alignEntry(android::ZipEntry* pEntry, uint32_t alignTo){
    if (alignTo == 0 || alignTo == 1)
        return OK;

    // Calculate where the entry payload offset will end up if we were to write
    // it as-is.
    uint64_t expectedPayloadOffset = ftello(mZipFp) +
        android::ZipEntry::LocalFileHeader::kLFHLen +
        pEntry->mLFH.mFileNameLength +
        pEntry->mLFH.mExtraFieldLength;

    // If the alignment is not what was requested, add some padding in the extra
    // so the payload ends up where is requested.
    uint64_t alignDiff = alignTo - (expectedPayloadOffset % alignTo);
    if (alignDiff == alignTo)
        return OK;

    return pEntry->addPadding(alignDiff);
}

/*
 * Add an entry by copying it from another zip file.  If "padding" is
 * nonzero, the specified number of bytes will be added to the "extra"
 * field in the header.
 *
 * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
 */
status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
    int alignTo, ZipEntry** ppEntry)
{
    ZipEntry* pEntry = NULL;
    status_t result;
    off_t lfhPosn, endPosn;

    if (mReadOnly)
        return INVALID_OPERATION;

    /* make sure we're in a reasonable state */
    assert(mZipFp != NULL);
    assert(mEntries.size() == mEOCD.mTotalNumEntries);

    if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
        result = UNKNOWN_ERROR;
        goto bail;
    }

    pEntry = new ZipEntry;
    if (pEntry == NULL) {
        result = NO_MEMORY;
        goto bail;
    }

    result = pEntry->initFromExternal(pSourceEntry);
    if (result != OK)
        goto bail;

    result = alignEntry(pEntry, alignTo);
    if (result != OK)
      goto bail;

    /*
     * From here on out, failures are more interesting.
     */
    mNeedCDRewrite = true;

    /*
     * Write the LFH.  Since we're not recompressing the data, we already
     * have all of the fields filled out.
     */
    lfhPosn = ftello(mZipFp);
    pEntry->mLFH.write(mZipFp);

    /*
     * Copy the data over.
     *
     * If the "has data descriptor" flag is set, we want to copy the DD
     * fields as well.  This is a fixed-size area immediately following
     * the data.
     */
    if (fseeko(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0) {
        result = UNKNOWN_ERROR;
        goto bail;
    }

    off_t copyLen;
    copyLen = pSourceEntry->getCompressedLen();
    if ((pSourceEntry->mLFH.mGPBitFlag & ZipEntry::kUsesDataDescr) != 0)
        copyLen += ZipEntry::kDataDescriptorLen;

    if (copyPartialFpToFp(mZipFp, pSourceZip->mZipFp, copyLen, NULL)
        != OK)
    {
        ALOGW("copy of '%s' failed\n", pEntry->mCDE.mFileName);
        result = UNKNOWN_ERROR;
        goto bail;
    }

    /*
     * Update file offsets.
     */
    endPosn = ftello(mZipFp);

    /*
     * Success!  Fill out new values.
     */
    pEntry->setLFHOffset(lfhPosn);      // sets mCDE.mLocalHeaderRelOffset
    mEOCD.mNumEntries++;
    mEOCD.mTotalNumEntries++;
    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
    mEOCD.mCentralDirOffset = endPosn;

    /*
     * Add pEntry to the list.
     */
    mEntries.add(pEntry);
    if (ppEntry != NULL)
        *ppEntry = pEntry;
    pEntry = NULL;

    result = OK;

bail:
    delete pEntry;
    return result;
}

/*
 * Add an entry by copying it from another zip file, recompressing with
 * Zopfli if already compressed.
 *
 * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
 */
status_t ZipFile::addRecompress(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
    ZipEntry** ppEntry)
{
    ZipEntry* pEntry = NULL;
    status_t result;
    off_t lfhPosn, uncompressedLen;

    if (mReadOnly)
        return INVALID_OPERATION;

    /* make sure we're in a reasonable state */
    assert(mZipFp != NULL);
    assert(mEntries.size() == mEOCD.mTotalNumEntries);

    if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
        result = UNKNOWN_ERROR;
        goto bail;
    }

    pEntry = new ZipEntry;
    if (pEntry == NULL) {
        result = NO_MEMORY;
        goto bail;
    }

    result = pEntry->initFromExternal(pSourceEntry);
    if (result != OK)
        goto bail;

    /*
     * From here on out, failures are more interesting.
     */
    mNeedCDRewrite = true;

    /*
     * Write the LFH, even though it's still mostly blank.  We need it
     * as a place-holder.  In theory the LFH isn't necessary, but in
     * practice some utilities demand it.
     */
    lfhPosn = ftello(mZipFp);
    pEntry->mLFH.write(mZipFp);

    /*
     * Copy the data over.
     *
     * If the "has data descriptor" flag is set, we want to copy the DD
     * fields as well.  This is a fixed-size area immediately following
     * the data.
     */
    if (fseeko(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0) {
        result = UNKNOWN_ERROR;
        goto bail;
    }

    uncompressedLen = pSourceEntry->getUncompressedLen();

    if (pSourceEntry->isCompressed()) {
        void *buf = pSourceZip->uncompress(pSourceEntry);
        if (buf == NULL) {
            result = NO_MEMORY;
            goto bail;
        }
        off_t startPosn = ftello(mZipFp);
        uint32_t crc;
        if (compressFpToFp(mZipFp, NULL, buf, uncompressedLen, &crc) != OK) {
            ALOGW("recompress of '%s' failed\n", pEntry->mCDE.mFileName);
            result = UNKNOWN_ERROR;
            free(buf);
            goto bail;
        }
        off_t endPosn = ftello(mZipFp);
        pEntry->setDataInfo(uncompressedLen, endPosn - startPosn,
            pSourceEntry->getCRC32(), ZipEntry::kCompressDeflated);
        free(buf);
    } else {
        off_t copyLen = pSourceEntry->getCompressedLen();
        if ((pSourceEntry->mLFH.mGPBitFlag & ZipEntry::kUsesDataDescr) != 0)
            copyLen += ZipEntry::kDataDescriptorLen;

        if (copyPartialFpToFp(mZipFp, pSourceZip->mZipFp, copyLen, NULL)
            != OK)
        {
            ALOGW("copy of '%s' failed\n", pEntry->mCDE.mFileName);
            result = UNKNOWN_ERROR;
            goto bail;
        }
    }

    /*
     * Success!  Fill out new values.
     */
    pEntry->setLFHOffset(lfhPosn);
    mEOCD.mNumEntries++;
    mEOCD.mTotalNumEntries++;
    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
    mEOCD.mCentralDirOffset = ftello(mZipFp);

    /*
     * Go back and write the LFH.
     */
    if (fseeko(mZipFp, lfhPosn, SEEK_SET) != 0) {
        result = UNKNOWN_ERROR;
        goto bail;
    }
    pEntry->mLFH.write(mZipFp);

    /*
     * Add pEntry to the list.
     */
    mEntries.add(pEntry);
    if (ppEntry != NULL)
        *ppEntry = pEntry;
    pEntry = NULL;

    result = OK;

bail:
    delete pEntry;
    return result;
}

/*
 * Copy all of the bytes in "src" to "dst".
 *
 * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
 * will be seeked immediately past the data.
 */
status_t ZipFile::copyFpToFp(FILE* dstFp, FILE* srcFp, uint32_t* pCRC32)
{
    uint8_t tmpBuf[32768];
    size_t count;

    *pCRC32 = crc32(0L, Z_NULL, 0);

    while (1) {
        count = fread(tmpBuf, 1, sizeof(tmpBuf), srcFp);
        if (ferror(srcFp) || ferror(dstFp)) {
            status_t status = errnoToStatus(errno);
            ALOGW("fread %zu bytes failed, %s", count, strerror(errno));
            return status;
        }
        if (count == 0)
            break;

        *pCRC32 = crc32(*pCRC32, tmpBuf, count);

        if (fwrite(tmpBuf, 1, count, dstFp) != count) {
            ALOGW("fwrite %zu bytes failed, %s", count, strerror(errno));
            return UNKNOWN_ERROR;
        }
    }

    return OK;
}

/*
 * Copy all of the bytes in "src" to "dst".
 *
 * On exit, "dstFp" will be seeked immediately past the data.
 */
status_t ZipFile::copyDataToFp(FILE* dstFp,
    const void* data, size_t size, uint32_t* pCRC32)
{
    *pCRC32 = crc32(0L, Z_NULL, 0);
    if (size > 0) {
        *pCRC32 = crc32(*pCRC32, (const unsigned char*)data, size);
        if (fwrite(data, 1, size, dstFp) != size) {
            ALOGW("fwrite %zu bytes failed, %s", size, strerror(errno));
            return UNKNOWN_ERROR;
        }
    }

    return OK;
}

/*
 * Copy some of the bytes in "src" to "dst".
 *
 * If "pCRC32" is NULL, the CRC will not be computed.
 *
 * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
 * will be seeked immediately past the data just written.
 */
status_t ZipFile::copyPartialFpToFp(FILE* dstFp, FILE* srcFp, size_t length,
    uint32_t* pCRC32)
{
    uint8_t tmpBuf[32768];
    size_t count;

    if (pCRC32 != NULL)
        *pCRC32 = crc32(0L, Z_NULL, 0);

    while (length) {
        size_t readSize;

        readSize = sizeof(tmpBuf);
        if (readSize > length)
            readSize = length;

        count = fread(tmpBuf, 1, readSize, srcFp);
        if (count != readSize) {     // error or unexpected EOF
            if (feof(srcFp)) {
                ALOGW("fread %zu bytes failed, unexpected EOF", readSize);
            } else {
                ALOGW("fread %zu bytes failed, %s", readSize, strerror(errno));
            }
            return UNKNOWN_ERROR;
        }

        if (pCRC32 != NULL)
            *pCRC32 = crc32(*pCRC32, tmpBuf, count);

        if (fwrite(tmpBuf, 1, count, dstFp) != count) {
            ALOGW("fwrite %zu bytes failed, %s", count, strerror(errno));
            return UNKNOWN_ERROR;
        }

        length -= readSize;
    }

    return OK;
}

/*
 * Compress all of the data in "srcFp" and write it to "dstFp".
 *
 * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
 * will be seeked immediately past the compressed data.
 */
status_t ZipFile::compressFpToFp(FILE* dstFp, FILE* srcFp,
    const void* data, size_t size, uint32_t* pCRC32)
{
    status_t result = OK;
    const size_t kBufSize = 1024 * 1024;
    uint8_t* inBuf = NULL;
    uint8_t* outBuf = NULL;
    size_t outSize = 0;
    bool atEof = false;     // no feof() aviailable yet
    uint32_t crc;
    ZopfliOptions options;
    unsigned char bp = 0;

    ZopfliInitOptions(&options);

    crc = crc32(0L, Z_NULL, 0);

    if (data) {
        crc = crc32(crc, (const unsigned char*)data, size);
        ZopfliDeflate(&options, 2, true, (const unsigned char*)data, size, &bp,
            &outBuf, &outSize);
    } else {
        /*
         * Create an input buffer and an output buffer.
         */
        inBuf = new uint8_t[kBufSize];
        if (inBuf == NULL) {
            result = NO_MEMORY;
            goto bail;
        }

        /*
         * Loop while we have data.
         */
        do {
            size_t getSize;
            getSize = fread(inBuf, 1, kBufSize, srcFp);
            if (ferror(srcFp)) {
                ALOGD("deflate read failed (errno=%d)\n", errno);
                result = UNKNOWN_ERROR;
                delete[] inBuf;
                goto bail;
            }
            if (getSize < kBufSize) {
                ALOGV("+++  got %zu bytes, EOF reached\n", getSize);
                atEof = true;
            }

            crc = crc32(crc, inBuf, getSize);
            ZopfliDeflate(&options, 2, atEof, inBuf, getSize, &bp, &outBuf, &outSize);
        } while (!atEof);
        delete[] inBuf;
    }

    ALOGV("+++ writing %zu bytes\n", outSize);
    if (fwrite(outBuf, 1, outSize, dstFp) != outSize) {
        ALOGW("fwrite %zu bytes failed, %s", outSize, strerror(errno));
        result = UNKNOWN_ERROR;
        goto bail;
    }

    *pCRC32 = crc;

bail:
    free(outBuf);

    return result;
}

/*
 * Mark an entry as deleted.
 *
 * We will eventually need to crunch the file down, but if several files
 * are being removed (perhaps as part of an "update" process) we can make
 * things considerably faster by deferring the removal to "flush" time.
 */
status_t ZipFile::remove(ZipEntry* pEntry)
{
    /*
     * Should verify that pEntry is actually part of this archive, and
     * not some stray ZipEntry from a different file.
     */

    /* mark entry as deleted, and mark archive as dirty */
    pEntry->setDeleted();
    mNeedCDRewrite = true;
    return OK;
}

/*
 * Flush any pending writes.
 *
 * In particular, this will crunch out deleted entries, and write the
 * Central Directory and EOCD if we have stomped on them.
 */
status_t ZipFile::flush(void)
{
    status_t result = OK;
    off_t eocdPosn;
    int i, count;

    if (mReadOnly)
        return INVALID_OPERATION;
    if (!mNeedCDRewrite)
        return OK;

    assert(mZipFp != NULL);

    result = crunchArchive();
    if (result != OK)
        return result;

    if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) return UNKNOWN_ERROR;

    count = mEntries.size();
    for (i = 0; i < count; i++) {
        ZipEntry* pEntry = mEntries[i];
        pEntry->mCDE.write(mZipFp);
    }

    eocdPosn = ftello(mZipFp);
    mEOCD.mCentralDirSize = eocdPosn - mEOCD.mCentralDirOffset;

    mEOCD.write(mZipFp);

    /*
     * If we had some stuff bloat up during compression and get replaced
     * with plain files, or if we deleted some entries, there's a lot
     * of wasted space at the end of the file.  Remove it now.
     */
    if (ftruncate(fileno(mZipFp), ftello(mZipFp)) != 0) {
        ALOGW("ftruncate failed %lld: %s\n", (long long) ftello(mZipFp), strerror(errno));
        // not fatal
    }

    /* should we clear the "newly added" flag in all entries now? */

    mNeedCDRewrite = false;
    return OK;
}

/*
 * Crunch deleted files out of an archive by shifting the later files down.
 *
 * Because we're not using a temp file, we do the operation inside the
 * current file.
 */
status_t ZipFile::crunchArchive(void)
{
    status_t result = OK;
    int i, count;
    long delCount, adjust;

#if 0
    printf("CONTENTS:\n");
    for (i = 0; i < (int) mEntries.size(); i++) {
        printf(" %d: lfhOff=%ld del=%d\n",
            i, mEntries[i]->getLFHOffset(), mEntries[i]->getDeleted());
    }
    printf("  END is %ld\n", (long) mEOCD.mCentralDirOffset);
#endif

    /*
     * Roll through the set of files, shifting them as appropriate.  We
     * could probably get a slight performance improvement by sliding
     * multiple files down at once (because we could use larger reads
     * when operating on batches of small files), but it's not that useful.
     */
    count = mEntries.size();
    delCount = adjust = 0;
    for (i = 0; i < count; i++) {
        ZipEntry* pEntry = mEntries[i];
        long span;

        if (pEntry->getLFHOffset() != 0) {
            long nextOffset;

            /* Get the length of this entry by finding the offset
             * of the next entry.  Directory entries don't have
             * file offsets, so we need to find the next non-directory
             * entry.
             */
            nextOffset = 0;
            for (int ii = i+1; nextOffset == 0 && ii < count; ii++)
                nextOffset = mEntries[ii]->getLFHOffset();
            if (nextOffset == 0)
                nextOffset = mEOCD.mCentralDirOffset;
            span = nextOffset - pEntry->getLFHOffset();

            assert(span >= ZipEntry::LocalFileHeader::kLFHLen);
        } else {
            /* This is a directory entry.  It doesn't have
             * any actual file contents, so there's no need to
             * move anything.
             */
            span = 0;
        }

        //printf("+++ %d: off=%ld span=%ld del=%d [count=%d]\n",
        //    i, pEntry->getLFHOffset(), span, pEntry->getDeleted(), count);

        if (pEntry->getDeleted()) {
            adjust += span;
            delCount++;

            delete pEntry;
            mEntries.removeAt(i);

            /* adjust loop control */
            count--;
            i--;
        } else if (span != 0 && adjust > 0) {
            /* shuffle this entry back */
            //printf("+++ Shuffling '%s' back %ld\n",
            //    pEntry->getFileName(), adjust);
            result = filemove(mZipFp, pEntry->getLFHOffset() - adjust,
                        pEntry->getLFHOffset(), span);
            if (result != OK) {
                /* this is why you use a temp file */
                ALOGE("error during crunch - archive is toast\n");
                return result;
            }

            pEntry->setLFHOffset(pEntry->getLFHOffset() - adjust);
        }
    }

    /*
     * Fix EOCD info.  We have to wait until the end to do some of this
     * because we use mCentralDirOffset to determine "span" for the
     * last entry.
     */
    mEOCD.mCentralDirOffset -= adjust;
    mEOCD.mNumEntries -= delCount;
    mEOCD.mTotalNumEntries -= delCount;
    mEOCD.mCentralDirSize = 0;  // mark invalid; set by flush()

    assert(mEOCD.mNumEntries == mEOCD.mTotalNumEntries);
    assert(mEOCD.mNumEntries == count);

    return result;
}

/*
 * Works like memmove(), but on pieces of a file.
 */
status_t ZipFile::filemove(FILE* fp, off_t dst, off_t src, size_t n)
{
    if (dst == src || n <= 0)
        return OK;

    uint8_t readBuf[32768];

    if (dst < src) {
        /* shift stuff toward start of file; must read from start */
        while (n != 0) {
            size_t getSize = sizeof(readBuf);
            if (getSize > n)
                getSize = n;

            if (fseeko(fp, src, SEEK_SET) != 0) {
                ALOGW("filemove src seek %lld failed, %s",
                    (long long) src, strerror(errno));
                return UNKNOWN_ERROR;
            }

            if (fread(readBuf, 1, getSize, fp) != getSize) {
                if (feof(fp)) {
                    ALOGW("fread %zu bytes off=%lld failed, unexpected EOF",
                        getSize, (long long) src);
                } else {
                    ALOGW("fread %zu bytes off=%lld failed, %s",
                        getSize, (long long) src, strerror(errno));
                }
                return UNKNOWN_ERROR;
            }

            if (fseeko(fp, dst, SEEK_SET) != 0) {
                ALOGW("filemove dst seek %lld failed, %s",
                    (long long) dst, strerror(errno));
                return UNKNOWN_ERROR;
            }

            if (fwrite(readBuf, 1, getSize, fp) != getSize) {
                ALOGW("filemove write %zu off=%lld failed, %s",
                    getSize, (long long) dst, strerror(errno));
                return UNKNOWN_ERROR;
            }

            src += getSize;
            dst += getSize;
            n -= getSize;
        }
    } else {
        /* shift stuff toward end of file; must read from end */
        assert(false);      // write this someday, maybe
        return UNKNOWN_ERROR;
    }

    return OK;
}


/*
 * Get the modification time from a file descriptor.
 */
time_t ZipFile::getModTime(int fd)
{
    struct stat sb;

    if (fstat(fd, &sb) < 0) {
        ALOGD("HEY: fstat on fd %d failed\n", fd);
        return (time_t) -1;
    }

    return sb.st_mtime;
}


#if 0       /* this is a bad idea */
/*
 * Get a copy of the Zip file descriptor.
 *
 * We don't allow this if the file was opened read-write because we tend
 * to leave the file contents in an uncertain state between calls to
 * flush().  The duplicated file descriptor should only be valid for reads.
 */
int ZipFile::getZipFd(void) const
{
    if (!mReadOnly)
        return INVALID_OPERATION;
    assert(mZipFp != NULL);

    int fd;
    fd = dup(fileno(mZipFp));
    if (fd < 0) {
        ALOGD("didn't work, errno=%d\n", errno);
    }

    return fd;
}
#endif


#if 0
/*
 * Expand data.
 */
bool ZipFile::uncompress(const ZipEntry* pEntry, void* buf) const
{
    return false;
}
#endif

class BufferWriter : public zip_archive::Writer {
  public:
    BufferWriter(void* buf, size_t size) : Writer(),
        buf_(reinterpret_cast<uint8_t*>(buf)), size_(size), bytes_written_(0) {}

    bool Append(uint8_t* buf, size_t buf_size) override {
        if (bytes_written_ + buf_size > size_) {
            return false;
        }

        memcpy(buf_ + bytes_written_, buf, buf_size);
        bytes_written_ += buf_size;
        return true;
    }

  private:
    uint8_t* const buf_;
    const size_t size_;
    size_t bytes_written_;
};

class FileReader : public zip_archive::Reader {
  public:
    FileReader(FILE* fp) : Reader(), fp_(fp), current_offset_(0) {
    }

    bool ReadAtOffset(uint8_t* buf, size_t len, off64_t offset) const {
        // Data is usually requested sequentially, so this helps avoid pointless
        // seeks every time we perform a read. There's an impedence mismatch
        // here because the original API was designed around pread and pwrite.
        if (offset != current_offset_) {
            if (fseeko(fp_, offset, SEEK_SET) != 0) {
                return false;
            }

            current_offset_ = offset;
        }

        size_t read = fread(buf, 1, len, fp_);
        if (read != len) {
            return false;
        }

        current_offset_ += read;
        return true;
    }

  private:
    FILE* fp_;
    mutable off64_t current_offset_;
};

// free the memory when you're done
void* ZipFile::uncompress(const ZipEntry* entry) const
{
    size_t unlen = entry->getUncompressedLen();
    size_t clen = entry->getCompressedLen();

    void* buf = malloc(unlen);
    if (buf == NULL) {
        return NULL;
    }

    fseeko(mZipFp, 0, SEEK_SET);

    off_t offset = entry->getFileOffset();
    if (fseeko(mZipFp, offset, SEEK_SET) != 0) {
        goto bail;
    }

    switch (entry->getCompressionMethod())
    {
        case ZipEntry::kCompressStored: {
            ssize_t amt = fread(buf, 1, unlen, mZipFp);
            if (amt != (ssize_t)unlen) {
                goto bail;
            }
#if 0
            printf("data...\n");
            const unsigned char* p = (unsigned char*)buf;
            const unsigned char* end = p+unlen;
            for (int i=0; i<32 && p < end; i++) {
                printf("0x%08x ", (int)(offset+(i*0x10)));
                for (int j=0; j<0x10 && p < end; j++) {
                    printf(" %02x", *p);
                    p++;
                }
                printf("\n");
            }
#endif

            }
            break;
        case ZipEntry::kCompressDeflated: {
            const FileReader reader(mZipFp);
            BufferWriter writer(buf, unlen);
            if (zip_archive::Inflate(reader, clen, unlen, &writer, nullptr) != 0) {
                goto bail;
            }
            break;
        }
        default:
            goto bail;
    }
    return buf;

bail:
    free(buf);
    return NULL;
}


/*
 * ===========================================================================
 *      ZipFile::EndOfCentralDir
 * ===========================================================================
 */

/*
 * Read the end-of-central-dir fields.
 *
 * "buf" should be positioned at the EOCD signature, and should contain
 * the entire EOCD area including the comment.
 */
status_t ZipFile::EndOfCentralDir::readBuf(const uint8_t* buf, int len)
{
    /* don't allow re-use */
    assert(mComment == NULL);

    if (len < kEOCDLen) {
        /* looks like ZIP file got truncated */
        ALOGD(" Zip EOCD: expected >= %d bytes, found %d\n",
            kEOCDLen, len);
        return INVALID_OPERATION;
    }

    /* this should probably be an assert() */
    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature)
        return UNKNOWN_ERROR;

    mDiskNumber = ZipEntry::getShortLE(&buf[0x04]);
    mDiskWithCentralDir = ZipEntry::getShortLE(&buf[0x06]);
    mNumEntries = ZipEntry::getShortLE(&buf[0x08]);
    mTotalNumEntries = ZipEntry::getShortLE(&buf[0x0a]);
    mCentralDirSize = ZipEntry::getLongLE(&buf[0x0c]);
    mCentralDirOffset = ZipEntry::getLongLE(&buf[0x10]);
    mCommentLen = ZipEntry::getShortLE(&buf[0x14]);

    // TODO: validate mCentralDirOffset

    if (mCommentLen > 0) {
        if (kEOCDLen + mCommentLen > len) {
            ALOGD("EOCD(%d) + comment(%" PRIu16 ") exceeds len (%d)\n",
                kEOCDLen, mCommentLen, len);
            return UNKNOWN_ERROR;
        }
        mComment = new uint8_t[mCommentLen];
        memcpy(mComment, buf + kEOCDLen, mCommentLen);
    }

    return OK;
}

/*
 * Write an end-of-central-directory section.
 */
status_t ZipFile::EndOfCentralDir::write(FILE* fp)
{
    uint8_t buf[kEOCDLen];

    ZipEntry::putLongLE(&buf[0x00], kSignature);
    ZipEntry::putShortLE(&buf[0x04], mDiskNumber);
    ZipEntry::putShortLE(&buf[0x06], mDiskWithCentralDir);
    ZipEntry::putShortLE(&buf[0x08], mNumEntries);
    ZipEntry::putShortLE(&buf[0x0a], mTotalNumEntries);
    ZipEntry::putLongLE(&buf[0x0c], mCentralDirSize);
    ZipEntry::putLongLE(&buf[0x10], mCentralDirOffset);
    ZipEntry::putShortLE(&buf[0x14], mCommentLen);

    if (fwrite(buf, 1, kEOCDLen, fp) != kEOCDLen) {
        ALOGW("fwrite EOCD failed, %s", strerror(errno));
        return UNKNOWN_ERROR;
    }
    if (mCommentLen > 0) {
        assert(mComment != NULL);
        if (fwrite(mComment, mCommentLen, 1, fp) != mCommentLen) {
            ALOGW("fwrite %d bytes failed, %s",
                (int) mCommentLen, strerror(errno));
            return UNKNOWN_ERROR;
        }
    }

    return OK;
}

/*
 * Dump the contents of an EndOfCentralDir object.
 */
void ZipFile::EndOfCentralDir::dump(void) const
{
    ALOGD(" EndOfCentralDir contents:\n");
    ALOGD("  diskNum=%" PRIu16 " diskWCD=%" PRIu16 " numEnt=%" PRIu16 " totalNumEnt=%" PRIu16 "\n",
        mDiskNumber, mDiskWithCentralDir, mNumEntries, mTotalNumEntries);
    ALOGD("  centDirSize=%" PRIu32 " centDirOff=%" PRIu32 " commentLen=%" PRIu32 "\n",
        mCentralDirSize, mCentralDirOffset, mCommentLen);
}

} // namespace android
