/*
 * 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 entries in a Zip archive.
//

#define LOG_TAG "zip"

#include "ZipEntry.h"
#include <utils/Log.h>

#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

using namespace android;

/*
 * Initialize a new ZipEntry structure from a FILE* positioned at a
 * CentralDirectoryEntry.
 *
 * On exit, the file pointer will be at the start of the next CDE or
 * at the EOCD.
 */
status_t ZipEntry::initFromCDE(FILE* fp)
{
    status_t result;
    long posn; // NOLINT(google-runtime-int), for ftell/fseek
    bool hasDD;

    //ALOGV("initFromCDE ---\n");

    /* read the CDE */
    result = mCDE.read(fp);
    if (result != OK) {
        ALOGD("mCDE.read failed\n");
        return result;
    }

    //mCDE.dump();

    /* using the info in the CDE, go load up the LFH */
    posn = ftell(fp);
    if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
        ALOGD("local header seek failed (%" PRIu32 ")\n",
            mCDE.mLocalHeaderRelOffset);
        return UNKNOWN_ERROR;
    }

    result = mLFH.read(fp);
    if (result != OK) {
        ALOGD("mLFH.read failed\n");
        return result;
    }

    if (fseek(fp, posn, SEEK_SET) != 0)
        return UNKNOWN_ERROR;

    //mLFH.dump();

    /*
     * We *might* need to read the Data Descriptor at this point and
     * integrate it into the LFH.  If this bit is set, the CRC-32,
     * compressed size, and uncompressed size will be zero.  In practice
     * these seem to be rare.
     */
    hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0;
    if (hasDD) {
        // do something clever
        //ALOGD("+++ has data descriptor\n");
    }

    /*
     * Sanity-check the LFH.  Note that this will fail if the "kUsesDataDescr"
     * flag is set, because the LFH is incomplete.  (Not a problem, since we
     * prefer the CDE values.)
     */
    if (!hasDD && !compareHeaders()) {
        ALOGW("WARNING: header mismatch\n");
        // keep going?
    }

    /*
     * If the mVersionToExtract is greater than 20, we may have an
     * issue unpacking the record -- could be encrypted, compressed
     * with something we don't support, or use Zip64 extensions.  We
     * can defer worrying about that to when we're extracting data.
     */

    return OK;
}

/*
 * Initialize a new entry.  Pass in the file name and an optional comment.
 *
 * Initializes the CDE and the LFH.
 */
void ZipEntry::initNew(const char* fileName, const char* comment)
{
    assert(fileName != NULL && *fileName != '\0');  // name required

    /* most fields are properly initialized by constructor */
    mCDE.mVersionMadeBy = kDefaultMadeBy;
    mCDE.mVersionToExtract = kDefaultVersion;
    mCDE.mCompressionMethod = kCompressStored;
    mCDE.mFileNameLength = strlen(fileName);
    if (comment != NULL)
        mCDE.mFileCommentLength = strlen(comment);
    mCDE.mExternalAttrs = 0x81b60020;   // matches what WinZip does

    if (mCDE.mFileNameLength > 0) {
        mCDE.mFileName = new uint8_t[mCDE.mFileNameLength+1];
        strcpy((char*) mCDE.mFileName, fileName);
    }
    if (mCDE.mFileCommentLength > 0) {
        /* TODO: stop assuming null-terminated ASCII here? */
        mCDE.mFileComment = new uint8_t[mCDE.mFileCommentLength+1];
        assert(comment != NULL);
        strcpy((char*) mCDE.mFileComment, comment);
    }

    copyCDEtoLFH();
}

/*
 * Initialize a new entry, starting with the ZipEntry from a different
 * archive.
 *
 * Initializes the CDE and the LFH.
 */
status_t ZipEntry::initFromExternal(const ZipEntry* pEntry)
{
    /*
     * Copy everything in the CDE over, then fix up the hairy bits.
     */
    memcpy(&mCDE, &pEntry->mCDE, sizeof(mCDE));

    if (mCDE.mFileNameLength > 0) {
        mCDE.mFileName = new uint8_t[mCDE.mFileNameLength+1];
        if (mCDE.mFileName == NULL)
            return NO_MEMORY;
        strcpy((char*) mCDE.mFileName, (char*)pEntry->mCDE.mFileName);
    }
    if (mCDE.mFileCommentLength > 0) {
        mCDE.mFileComment = new uint8_t[mCDE.mFileCommentLength+1];
        if (mCDE.mFileComment == NULL)
            return NO_MEMORY;
        strcpy((char*) mCDE.mFileComment, (char*)pEntry->mCDE.mFileComment);
    }
    if (mCDE.mExtraFieldLength > 0) {
        /* we null-terminate this, though it may not be a string */
        mCDE.mExtraField = new uint8_t[mCDE.mExtraFieldLength+1];
        if (mCDE.mExtraField == NULL)
            return NO_MEMORY;
        memcpy(mCDE.mExtraField, pEntry->mCDE.mExtraField,
            mCDE.mExtraFieldLength+1);
    }

    /* construct the LFH from the CDE */
    copyCDEtoLFH();

    /*
     * The LFH "extra" field is independent of the CDE "extra", so we
     * handle it here.
     */
    assert(mLFH.mExtraField == NULL);
    mLFH.mExtraFieldLength = pEntry->mLFH.mExtraFieldLength;
    if (mLFH.mExtraFieldLength > 0) {
        mLFH.mExtraField = new uint8_t[mLFH.mExtraFieldLength+1];
        if (mLFH.mExtraField == NULL)
            return NO_MEMORY;
        memcpy(mLFH.mExtraField, pEntry->mLFH.mExtraField,
            mLFH.mExtraFieldLength+1);
    }

    return OK;
}

/*
 * Insert pad bytes in the LFH by tweaking the "extra" field.  This will
 * potentially confuse something that put "extra" data in here earlier,
 * but I can't find an actual problem.
 */
status_t ZipEntry::addPadding(int padding)
{
    if (padding <= 0)
        return INVALID_OPERATION;

    //ALOGI("HEY: adding %d pad bytes to existing %d in %s\n",
    //    padding, mLFH.mExtraFieldLength, mCDE.mFileName);

    if (mLFH.mExtraFieldLength > 0) {
        /* extend existing field */
        uint8_t* newExtra;

        newExtra = new uint8_t[mLFH.mExtraFieldLength + padding];
        if (newExtra == NULL)
            return NO_MEMORY;
        memset(newExtra + mLFH.mExtraFieldLength, 0, padding);
        memcpy(newExtra, mLFH.mExtraField, mLFH.mExtraFieldLength);

        delete[] mLFH.mExtraField;
        mLFH.mExtraField = newExtra;
        mLFH.mExtraFieldLength += padding;
    } else {
        /* create new field */
        mLFH.mExtraField = new uint8_t[padding];
        memset(mLFH.mExtraField, 0, padding);
        mLFH.mExtraFieldLength = padding;
    }

    return OK;
}

/*
 * Set the fields in the LFH equal to the corresponding fields in the CDE.
 *
 * This does not touch the LFH "extra" field.
 */
void ZipEntry::copyCDEtoLFH(void)
{
    mLFH.mVersionToExtract  = mCDE.mVersionToExtract;
    mLFH.mGPBitFlag         = mCDE.mGPBitFlag;
    mLFH.mCompressionMethod = mCDE.mCompressionMethod;
    mLFH.mLastModFileTime   = mCDE.mLastModFileTime;
    mLFH.mLastModFileDate   = mCDE.mLastModFileDate;
    mLFH.mCRC32             = mCDE.mCRC32;
    mLFH.mCompressedSize    = mCDE.mCompressedSize;
    mLFH.mUncompressedSize  = mCDE.mUncompressedSize;
    mLFH.mFileNameLength    = mCDE.mFileNameLength;
    // the "extra field" is independent

    delete[] mLFH.mFileName;
    if (mLFH.mFileNameLength > 0) {
        mLFH.mFileName = new uint8_t[mLFH.mFileNameLength+1];
        strcpy((char*) mLFH.mFileName, (const char*) mCDE.mFileName);
    } else {
        mLFH.mFileName = NULL;
    }
}

/*
 * Set some information about a file after we add it.
 */
void ZipEntry::setDataInfo(uint32_t uncompLen, uint32_t compLen, uint32_t crc32,
    uint32_t compressionMethod)
{
    mCDE.mCompressionMethod = compressionMethod;
    mCDE.mCRC32 = crc32;
    mCDE.mCompressedSize = compLen;
    mCDE.mUncompressedSize = uncompLen;
    mCDE.mCompressionMethod = compressionMethod;
    if (compressionMethod == kCompressDeflated) {
        mCDE.mGPBitFlag |= 0x0002;      // indicates maximum compression used
    }
    copyCDEtoLFH();
}

/*
 * See if the data in mCDE and mLFH match up.  This is mostly useful for
 * debugging these classes, but it can be used to identify damaged
 * archives.
 *
 * Returns "false" if they differ.
 */
bool ZipEntry::compareHeaders(void) const
{
    if (mCDE.mVersionToExtract != mLFH.mVersionToExtract) {
        ALOGV("cmp: VersionToExtract\n");
        return false;
    }
    if (mCDE.mGPBitFlag != mLFH.mGPBitFlag) {
        ALOGV("cmp: GPBitFlag\n");
        return false;
    }
    if (mCDE.mCompressionMethod != mLFH.mCompressionMethod) {
        ALOGV("cmp: CompressionMethod\n");
        return false;
    }
    if (mCDE.mLastModFileTime != mLFH.mLastModFileTime) {
        ALOGV("cmp: LastModFileTime\n");
        return false;
    }
    if (mCDE.mLastModFileDate != mLFH.mLastModFileDate) {
        ALOGV("cmp: LastModFileDate\n");
        return false;
    }
    if (mCDE.mCRC32 != mLFH.mCRC32) {
        ALOGV("cmp: CRC32\n");
        return false;
    }
    if (mCDE.mCompressedSize != mLFH.mCompressedSize) {
        ALOGV("cmp: CompressedSize\n");
        return false;
    }
    if (mCDE.mUncompressedSize != mLFH.mUncompressedSize) {
        ALOGV("cmp: UncompressedSize\n");
        return false;
    }
    if (mCDE.mFileNameLength != mLFH.mFileNameLength) {
        ALOGV("cmp: FileNameLength\n");
        return false;
    }
#if 0       // this seems to be used for padding, not real data
    if (mCDE.mExtraFieldLength != mLFH.mExtraFieldLength) {
        ALOGV("cmp: ExtraFieldLength\n");
        return false;
    }
#endif
    if (mCDE.mFileName != NULL) {
        if (strcmp((char*) mCDE.mFileName, (char*) mLFH.mFileName) != 0) {
            ALOGV("cmp: FileName\n");
            return false;
        }
    }

    return true;
}


/*
 * Convert the DOS date/time stamp into a UNIX time stamp.
 */
time_t ZipEntry::getModWhen(void) const
{
    struct tm parts;

    parts.tm_sec = (mCDE.mLastModFileTime & 0x001f) << 1;
    parts.tm_min = (mCDE.mLastModFileTime & 0x07e0) >> 5;
    parts.tm_hour = (mCDE.mLastModFileTime & 0xf800) >> 11;
    parts.tm_mday = (mCDE.mLastModFileDate & 0x001f);
    parts.tm_mon = ((mCDE.mLastModFileDate & 0x01e0) >> 5) -1;
    parts.tm_year = ((mCDE.mLastModFileDate & 0xfe00) >> 9) + 80;
    parts.tm_wday = parts.tm_yday = 0;
    parts.tm_isdst = -1;        // DST info "not available"

    return mktime(&parts);
}

/*
 * Set the CDE/LFH timestamp from UNIX time.
 */
void ZipEntry::setModWhen(time_t when)
{
#if !defined(_WIN32)
    struct tm tmResult;
#endif
    time_t even;
    uint16_t zdate, ztime;

    struct tm* ptm;

    /* round up to an even number of seconds */
    even = (when & 1) ? (when + 1) : when;

    /* expand */
#if !defined(_WIN32)
    ptm = localtime_r(&even, &tmResult);
#else
    ptm = localtime(&even);
#endif

    int year;
    year = ptm->tm_year;
    if (year < 80)
        year = 80;

    zdate = (year - 80) << 9 | (ptm->tm_mon+1) << 5 | ptm->tm_mday;
    ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;

    mCDE.mLastModFileTime = mLFH.mLastModFileTime = ztime;
    mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate;
}


/*
 * ===========================================================================
 *      ZipEntry::LocalFileHeader
 * ===========================================================================
 */

/*
 * Read a local file header.
 *
 * On entry, "fp" points to the signature at the start of the header.
 * On exit, "fp" points to the start of data.
 */
status_t ZipEntry::LocalFileHeader::read(FILE* fp)
{
    status_t result = OK;
    uint8_t buf[kLFHLen];

    assert(mFileName == NULL);
    assert(mExtraField == NULL);

    if (fread(buf, 1, kLFHLen, fp) != kLFHLen) {
        result = UNKNOWN_ERROR;
        goto bail;
    }

    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
        ALOGD("whoops: didn't find expected signature\n");
        result = UNKNOWN_ERROR;
        goto bail;
    }

    mVersionToExtract = ZipEntry::getShortLE(&buf[0x04]);
    mGPBitFlag = ZipEntry::getShortLE(&buf[0x06]);
    mCompressionMethod = ZipEntry::getShortLE(&buf[0x08]);
    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0a]);
    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0c]);
    mCRC32 = ZipEntry::getLongLE(&buf[0x0e]);
    mCompressedSize = ZipEntry::getLongLE(&buf[0x12]);
    mUncompressedSize = ZipEntry::getLongLE(&buf[0x16]);
    mFileNameLength = ZipEntry::getShortLE(&buf[0x1a]);
    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1c]);

    // TODO: validate sizes

    /* grab filename */
    if (mFileNameLength != 0) {
        mFileName = new uint8_t[mFileNameLength+1];
        if (mFileName == NULL) {
            result = NO_MEMORY;
            goto bail;
        }
        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
            result = UNKNOWN_ERROR;
            goto bail;
        }
        mFileName[mFileNameLength] = '\0';
    }

    /* grab extra field */
    if (mExtraFieldLength != 0) {
        mExtraField = new uint8_t[mExtraFieldLength+1];
        if (mExtraField == NULL) {
            result = NO_MEMORY;
            goto bail;
        }
        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
            result = UNKNOWN_ERROR;
            goto bail;
        }
        mExtraField[mExtraFieldLength] = '\0';
    }

bail:
    return result;
}

/*
 * Write a local file header.
 */
status_t ZipEntry::LocalFileHeader::write(FILE* fp)
{
    uint8_t buf[kLFHLen];

    ZipEntry::putLongLE(&buf[0x00], kSignature);
    ZipEntry::putShortLE(&buf[0x04], mVersionToExtract);
    ZipEntry::putShortLE(&buf[0x06], mGPBitFlag);
    ZipEntry::putShortLE(&buf[0x08], mCompressionMethod);
    ZipEntry::putShortLE(&buf[0x0a], mLastModFileTime);
    ZipEntry::putShortLE(&buf[0x0c], mLastModFileDate);
    ZipEntry::putLongLE(&buf[0x0e], mCRC32);
    ZipEntry::putLongLE(&buf[0x12], mCompressedSize);
    ZipEntry::putLongLE(&buf[0x16], mUncompressedSize);
    ZipEntry::putShortLE(&buf[0x1a], mFileNameLength);
    ZipEntry::putShortLE(&buf[0x1c], mExtraFieldLength);

    if (fwrite(buf, 1, kLFHLen, fp) != kLFHLen)
        return UNKNOWN_ERROR;

    /* write filename */
    if (mFileNameLength != 0) {
        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
            return UNKNOWN_ERROR;
    }

    /* write "extra field" */
    if (mExtraFieldLength != 0) {
        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
            return UNKNOWN_ERROR;
    }

    return OK;
}


/*
 * Dump the contents of a LocalFileHeader object.
 */
void ZipEntry::LocalFileHeader::dump(void) const
{
    ALOGD(" LocalFileHeader contents:\n");
    ALOGD("  versToExt=%" PRIu16 " gpBits=0x%04" PRIx16 " compression=%" PRIu16 "\n",
        mVersionToExtract, mGPBitFlag, mCompressionMethod);
    ALOGD("  modTime=0x%04" PRIx16 " modDate=0x%04" PRIx16 " crc32=0x%08" PRIx32 "\n",
        mLastModFileTime, mLastModFileDate, mCRC32);
    ALOGD("  compressedSize=%" PRIu32 " uncompressedSize=%" PRIu32 "\n",
        mCompressedSize, mUncompressedSize);
    ALOGD("  filenameLen=%" PRIu16 " extraLen=%" PRIu16 "\n",
        mFileNameLength, mExtraFieldLength);
    if (mFileName != NULL)
        ALOGD("  filename: '%s'\n", mFileName);
}


/*
 * ===========================================================================
 *      ZipEntry::CentralDirEntry
 * ===========================================================================
 */

/*
 * Read the central dir entry that appears next in the file.
 *
 * On entry, "fp" should be positioned on the signature bytes for the
 * entry.  On exit, "fp" will point at the signature word for the next
 * entry or for the EOCD.
 */
status_t ZipEntry::CentralDirEntry::read(FILE* fp)
{
    status_t result = OK;
    uint8_t buf[kCDELen];

    /* no re-use */
    assert(mFileName == NULL);
    assert(mExtraField == NULL);
    assert(mFileComment == NULL);

    if (fread(buf, 1, kCDELen, fp) != kCDELen) {
        result = UNKNOWN_ERROR;
        goto bail;
    }

    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
        ALOGD("Whoops: didn't find expected signature\n");
        result = UNKNOWN_ERROR;
        goto bail;
    }

    mVersionMadeBy = ZipEntry::getShortLE(&buf[0x04]);
    mVersionToExtract = ZipEntry::getShortLE(&buf[0x06]);
    mGPBitFlag = ZipEntry::getShortLE(&buf[0x08]);
    mCompressionMethod = ZipEntry::getShortLE(&buf[0x0a]);
    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0c]);
    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0e]);
    mCRC32 = ZipEntry::getLongLE(&buf[0x10]);
    mCompressedSize = ZipEntry::getLongLE(&buf[0x14]);
    mUncompressedSize = ZipEntry::getLongLE(&buf[0x18]);
    mFileNameLength = ZipEntry::getShortLE(&buf[0x1c]);
    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1e]);
    mFileCommentLength = ZipEntry::getShortLE(&buf[0x20]);
    mDiskNumberStart = ZipEntry::getShortLE(&buf[0x22]);
    mInternalAttrs = ZipEntry::getShortLE(&buf[0x24]);
    mExternalAttrs = ZipEntry::getLongLE(&buf[0x26]);
    mLocalHeaderRelOffset = ZipEntry::getLongLE(&buf[0x2a]);

    // TODO: validate sizes and offsets

    /* grab filename */
    if (mFileNameLength != 0) {
        mFileName = new uint8_t[mFileNameLength+1];
        if (mFileName == NULL) {
            result = NO_MEMORY;
            goto bail;
        }
        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
            result = UNKNOWN_ERROR;
            goto bail;
        }
        mFileName[mFileNameLength] = '\0';
    }

    /* read "extra field" */
    if (mExtraFieldLength != 0) {
        mExtraField = new uint8_t[mExtraFieldLength+1];
        if (mExtraField == NULL) {
            result = NO_MEMORY;
            goto bail;
        }
        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
            result = UNKNOWN_ERROR;
            goto bail;
        }
        mExtraField[mExtraFieldLength] = '\0';
    }


    /* grab comment, if any */
    if (mFileCommentLength != 0) {
        mFileComment = new uint8_t[mFileCommentLength+1];
        if (mFileComment == NULL) {
            result = NO_MEMORY;
            goto bail;
        }
        if (fread(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
        {
            result = UNKNOWN_ERROR;
            goto bail;
        }
        mFileComment[mFileCommentLength] = '\0';
    }

bail:
    return result;
}

/*
 * Write a central dir entry.
 */
status_t ZipEntry::CentralDirEntry::write(FILE* fp)
{
    uint8_t buf[kCDELen];

    ZipEntry::putLongLE(&buf[0x00], kSignature);
    ZipEntry::putShortLE(&buf[0x04], mVersionMadeBy);
    ZipEntry::putShortLE(&buf[0x06], mVersionToExtract);
    ZipEntry::putShortLE(&buf[0x08], mGPBitFlag);
    ZipEntry::putShortLE(&buf[0x0a], mCompressionMethod);
    ZipEntry::putShortLE(&buf[0x0c], mLastModFileTime);
    ZipEntry::putShortLE(&buf[0x0e], mLastModFileDate);
    ZipEntry::putLongLE(&buf[0x10], mCRC32);
    ZipEntry::putLongLE(&buf[0x14], mCompressedSize);
    ZipEntry::putLongLE(&buf[0x18], mUncompressedSize);
    ZipEntry::putShortLE(&buf[0x1c], mFileNameLength);
    ZipEntry::putShortLE(&buf[0x1e], mExtraFieldLength);
    ZipEntry::putShortLE(&buf[0x20], mFileCommentLength);
    ZipEntry::putShortLE(&buf[0x22], mDiskNumberStart);
    ZipEntry::putShortLE(&buf[0x24], mInternalAttrs);
    ZipEntry::putLongLE(&buf[0x26], mExternalAttrs);
    ZipEntry::putLongLE(&buf[0x2a], mLocalHeaderRelOffset);

    if (fwrite(buf, 1, kCDELen, fp) != kCDELen)
        return UNKNOWN_ERROR;

    /* write filename */
    if (mFileNameLength != 0) {
        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
            return UNKNOWN_ERROR;
    }

    /* write "extra field" */
    if (mExtraFieldLength != 0) {
        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
            return UNKNOWN_ERROR;
    }

    /* write comment */
    if (mFileCommentLength != 0) {
        if (fwrite(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
            return UNKNOWN_ERROR;
    }

    return OK;
}

/*
 * Dump the contents of a CentralDirEntry object.
 */
void ZipEntry::CentralDirEntry::dump(void) const
{
    ALOGD(" CentralDirEntry contents:\n");
    ALOGD("  versMadeBy=%" PRIu16 " versToExt=%" PRIu16 " gpBits=0x%04" PRIx16 " compression=%" PRIu16 "\n",
        mVersionMadeBy, mVersionToExtract, mGPBitFlag, mCompressionMethod);
    ALOGD("  modTime=0x%04" PRIx16 " modDate=0x%04" PRIx16 " crc32=0x%08" PRIx32 "\n",
        mLastModFileTime, mLastModFileDate, mCRC32);
    ALOGD("  compressedSize=%" PRIu32 " uncompressedSize=%" PRIu32 "\n",
        mCompressedSize, mUncompressedSize);
    ALOGD("  filenameLen=%" PRIu16 " extraLen=%" PRIu16 " commentLen=%" PRIu16 "\n",
        mFileNameLength, mExtraFieldLength, mFileCommentLength);
    ALOGD("  diskNumStart=%" PRIu16 " intAttr=0x%04" PRIx16 " extAttr=0x%08" PRIx32 " relOffset=%" PRIu32 "\n",
        mDiskNumberStart, mInternalAttrs, mExternalAttrs,
        mLocalHeaderRelOffset);

    if (mFileName != NULL)
        ALOGD("  filename: '%s'\n", mFileName);
    if (mFileComment != NULL)
        ALOGD("  comment: '%s'\n", mFileComment);
}

