Example #1
0
void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
{
  Byte allAreDefined = ReadByte();
  if (allAreDefined == 0)
  {
    ReadBoolVector(numItems, v);
    return;
  }
  v.Clear();
  v.Reserve(numItems);
  for (int i = 0; i < numItems; i++)
    v.Add(true);
}
Example #2
0
void CInArchive::ReadBoolVector(int numItems, CBoolVector &v)
{
  v.Clear();
  v.Reserve(numItems);
  Byte b = 0;
  Byte mask = 0;
  for (int i = 0; i < numItems; i++)
  {
    if (mask == 0)
    {
      b = ReadByte();
      mask = 0x80;
    }
    v.Add((b & mask) != 0);
    mask >>= 1;
  }
}
Example #3
0
File: 7zIn.cpp Project: bks/qz7
HRESULT CInArchive::ReadHeader(
    DECL_EXTERNAL_CODECS_LOC_VARS
    CArchiveDatabaseEx &db
#ifndef _NO_CRYPTO
    , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
#endif
)
{
    UInt64 type = ReadID();

    if (type == NID::kArchiveProperties)
    {
        ReadArchiveProperties(db.ArchiveInfo);
        type = ReadID();
    }

    CObjectVector<CByteBuffer> dataVector;

    if (type == NID::kAdditionalStreamsInfo)
    {
        HRESULT result = ReadAndDecodePackedStreams(
                             EXTERNAL_CODECS_LOC_VARS
                             db.ArchiveInfo.StartPositionAfterHeader,
                             db.ArchiveInfo.DataStartPosition2,
                             dataVector
#ifndef _NO_CRYPTO
                             , getTextPassword, passwordIsDefined
#endif
                         );
        RINOK(result);
        db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
        type = ReadID();
    }

    CRecordVector<UInt64> unpackSizes;
    CRecordVector<bool> digestsDefined;
    CRecordVector<UInt32> digests;

    if (type == NID::kMainStreamsInfo)
    {
        ReadStreamsInfo(&dataVector,
                        db.ArchiveInfo.DataStartPosition,
                        db.PackSizes,
                        db.PackCRCsDefined,
                        db.PackCRCs,
                        db.Folders,
                        db.NumUnpackStreamsVector,
                        unpackSizes,
                        digestsDefined,
                        digests);
        db.ArchiveInfo.DataStartPosition += db.ArchiveInfo.StartPositionAfterHeader;
        type = ReadID();
    }
    else
    {
        for (int i = 0; i < db.Folders.Size(); i++)
        {
            db.NumUnpackStreamsVector.Add(1);
            CFolder &folder = db.Folders[i];
            unpackSizes.Add(folder.GetUnpackSize());
            digestsDefined.Add(folder.UnpackCRCDefined);
            digests.Add(folder.UnpackCRC);
        }
    }

    db.Files.Clear();

    if (type == NID::kEnd)
        return S_OK;
    if (type != NID::kFilesInfo)
        ThrowIncorrect();

    CNum numFiles = ReadNum();
    db.Files.Reserve(numFiles);
    CNum i;
    for (i = 0; i < numFiles; i++)
        db.Files.Add(CFileItem());

    db.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
    if (!db.PackSizes.IsEmpty())
        db.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
    if (numFiles > 0  && !digests.IsEmpty())
        db.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);

    CBoolVector emptyStreamVector;
    emptyStreamVector.Reserve((int)numFiles);
    for (i = 0; i < numFiles; i++)
        emptyStreamVector.Add(false);
    CBoolVector emptyFileVector;
    CBoolVector antiFileVector;
    CNum numEmptyStreams = 0;

    for (;;)
    {
        UInt64 type = ReadID();
        if (type == NID::kEnd)
            break;
        UInt64 size = ReadNumber();
        size_t ppp = _inByteBack->_pos;
        bool addPropIdToList = true;
        bool isKnownType = true;
        if (type > ((UInt32)1 << 30))
            isKnownType = false;
        else switch((UInt32)type)
            {
            case NID::kName:
            {
                CStreamSwitch streamSwitch;
                streamSwitch.Set(this, &dataVector);
                for (int i = 0; i < db.Files.Size(); i++)
                    _inByteBack->ReadString(db.Files[i].Name);
                break;
            }
            case NID::kWinAttributes:
            {
                CBoolVector boolVector;
                ReadBoolVector2(db.Files.Size(), boolVector);
                CStreamSwitch streamSwitch;
                streamSwitch.Set(this, &dataVector);
                for (i = 0; i < numFiles; i++)
                {
                    CFileItem &file = db.Files[i];
                    file.AttribDefined = boolVector[i];
                    if (file.AttribDefined)
                        file.Attrib = ReadUInt32();
                }
                break;
            }
            case NID::kEmptyStream:
            {
                ReadBoolVector(numFiles, emptyStreamVector);
                for (i = 0; i < (CNum)emptyStreamVector.Size(); i++)
                    if (emptyStreamVector[i])
                        numEmptyStreams++;
                emptyFileVector.Reserve(numEmptyStreams);
                antiFileVector.Reserve(numEmptyStreams);
                for (i = 0; i < numEmptyStreams; i++)
                {
                    emptyFileVector.Add(false);
                    antiFileVector.Add(false);
                }
                break;
            }
            case NID::kEmptyFile:
                ReadBoolVector(numEmptyStreams, emptyFileVector);
                break;
            case NID::kAnti:
                ReadBoolVector(numEmptyStreams, antiFileVector);
                break;
            case NID::kStartPos:
                ReadUInt64DefVector(dataVector, db.StartPos, (int)numFiles);
                break;
            case NID::kCTime:
                ReadUInt64DefVector(dataVector, db.CTime, (int)numFiles);
                break;
            case NID::kATime:
                ReadUInt64DefVector(dataVector, db.ATime, (int)numFiles);
                break;
            case NID::kMTime:
                ReadUInt64DefVector(dataVector, db.MTime, (int)numFiles);
                break;
            case NID::kDummy:
            {
                for (UInt64 j = 0; j < size; j++)
                    if (ReadByte() != 0)
                        ThrowIncorrect();
                addPropIdToList = false;
                break;
            }
            default:
                addPropIdToList = isKnownType = false;
            }
        if (isKnownType)
        {
            if(addPropIdToList)
                db.ArchiveInfo.FileInfoPopIDs.Add(type);
        }
        else
            SkeepData(size);
        bool checkRecordsSize = (db.ArchiveInfo.Version.Major > 0 ||
                                 db.ArchiveInfo.Version.Minor > 2);
        if (checkRecordsSize && _inByteBack->_pos - ppp != size)
            ThrowIncorrect();
    }

    CNum emptyFileIndex = 0;
    CNum sizeIndex = 0;

    CNum numAntiItems = 0;
    for (i = 0; i < numEmptyStreams; i++)
        if (antiFileVector[i])
            numAntiItems++;

    for (i = 0; i < numFiles; i++)
    {
        CFileItem &file = db.Files[i];
        bool isAnti;
        file.HasStream = !emptyStreamVector[i];
        if (file.HasStream)
        {
            file.IsDir = false;
            isAnti = false;
            file.Size = unpackSizes[sizeIndex];
            file.Crc = digests[sizeIndex];
            file.CrcDefined = digestsDefined[sizeIndex];
            sizeIndex++;
        }
        else
        {
            file.IsDir = !emptyFileVector[emptyFileIndex];
            isAnti = antiFileVector[emptyFileIndex];
            emptyFileIndex++;
            file.Size = 0;
            file.CrcDefined = false;
        }
        if (numAntiItems != 0)
            db.IsAnti.Add(isAnti);
    }
    return S_OK;
}