/*
 * 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 <stdio.h>
#include <string.h>
#include <assert.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;
    bool hasDD;

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

    /* read the CDE */
    result = mCDE.read(fp);
    if (result != NO_ERROR) {
        LOGD("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) {
        LOGD("local header seek failed (%ld)\n",
            mCDE.mLocalHeaderRelOffset);
        return UNKNOWN_ERROR;
    }

    result = mLFH.read(fp);
    if (result != NO_ERROR) {
        LOGD("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
        //LOGD("+++ 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()) {
        LOGW("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 NO_ERROR;
}

/*
 * 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 unsigned char[mCDE.mFileNameLength+1];
        strcpy((char*) mCDE.mFileName, fileName);
    }
    if (mCDE.mFileCommentLength > 0) {
        /* TODO: stop assuming null-terminated ASCII here? */
        mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
        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 ZipFile* pZipFile,
    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 unsigned char[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 unsigned char[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 unsigned char[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 unsigned char[mLFH.mExtraFieldLength+1];
        if (mLFH.mExtraField == NULL)
            return NO_MEMORY;
        memcpy(mLFH.mExtraField, pEntry->mLFH.mExtraField,
            mLFH.mExtraFieldLength+1);
    }

    return NO_ERROR;
}

/*
 * 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;

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

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

        newExtra = new unsigned char[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 unsigned char[padding];
        memset(mLFH.mExtraField, 0, padding);
        mLFH.mExtraFieldLength = padding;
    }

    return NO_ERROR;
}

/*
 * 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 unsigned char[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(long uncompLen, long compLen, unsigned long crc32,
    int 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)
{
#ifdef HAVE_LOCALTIME_R
    struct tm tmResult;
#endif
    time_t even;
    unsigned short zdate, ztime;

    struct tm* ptm;

    /* round up to an even number of seconds */
    even = (time_t)(((unsigned long)(when) + 1) & (~1));

    /* expand */
#ifdef HAVE_LOCALTIME_R
    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 = NO_ERROR;
    unsigned char 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) {
        LOGD("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 unsigned char[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 unsigned char[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)
{
    unsigned char 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 NO_ERROR;
}


/*
 * Dump the contents of a LocalFileHeader object.
 */
void ZipEntry::LocalFileHeader::dump(void) const
{
    LOGD(" LocalFileHeader contents:\n");
    LOGD("  versToExt=%u gpBits=0x%04x compression=%u\n",
        mVersionToExtract, mGPBitFlag, mCompressionMethod);
    LOGD("  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
        mLastModFileTime, mLastModFileDate, mCRC32);
    LOGD("  compressedSize=%lu uncompressedSize=%lu\n",
        mCompressedSize, mUncompressedSize);
    LOGD("  filenameLen=%u extraLen=%u\n",
        mFileNameLength, mExtraFieldLength);
    if (mFileName != NULL)
        LOGD("  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 = NO_ERROR;
    unsigned char 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) {
        LOGD("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 unsigned char[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 unsigned char[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 unsigned char[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)
{
    unsigned char 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 NO_ERROR;
}

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

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

