⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 7zin.cpp

📁 压缩软件源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
}

HRESULT CInArchive::WaitAttribute(UInt64 attribute)
{
  while(true)
  {
    UInt64 type;
    RINOK(ReadID(type));
    if (type == attribute)
      return S_OK;
    if (type == NID::kEnd)
      return S_FALSE;
    RINOK(SkeepData());
  }
}

HRESULT CInArchive::ReadHashDigests(int numItems,
    CRecordVector<bool> &digestsDefined, 
    CRecordVector<UInt32> &digests)
{
  RINOK(ReadBoolVector2(numItems, digestsDefined));
  digests.Clear();
  digests.Reserve(numItems);
  for(int i = 0; i < numItems; i++)
  {
    UInt32 crc;
    if (digestsDefined[i])
      RINOK(ReadUInt32(crc));
    digests.Add(crc);
  }
  return S_OK;
}

HRESULT CInArchive::ReadPackInfo(
    UInt64 &dataOffset,
    CRecordVector<UInt64> &packSizes,
    CRecordVector<bool> &packCRCsDefined,
    CRecordVector<UInt32> &packCRCs)
{
  RINOK(ReadNumber(dataOffset));
  CNum numPackStreams;
  RINOK(ReadNum(numPackStreams));

  RINOK(WaitAttribute(NID::kSize));
  packSizes.Clear();
  packSizes.Reserve(numPackStreams);
  for(CNum i = 0; i < numPackStreams; i++)
  {
    UInt64 size;
    RINOK(ReadNumber(size));
    packSizes.Add(size);
  }

  UInt64 type;
  while(true)
  {
    RINOK(ReadID(type));
    if (type == NID::kEnd)
      break;
    if (type == NID::kCRC)
    {
      RINOK(ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs)); 
      continue;
    }
    RINOK(SkeepData());
  }
  if (packCRCsDefined.IsEmpty())
  {
    packCRCsDefined.Reserve(numPackStreams);
    packCRCsDefined.Clear();
    packCRCs.Reserve(numPackStreams);
    packCRCs.Clear();
    for(CNum i = 0; i < numPackStreams; i++)
    {
      packCRCsDefined.Add(false);
      packCRCs.Add(0);
    }
  }
  return S_OK;
}

HRESULT CInArchive::ReadUnPackInfo(
    const CObjectVector<CByteBuffer> *dataVector,
    CObjectVector<CFolder> &folders)
{
  RINOK(WaitAttribute(NID::kFolder));
  CNum numFolders;
  RINOK(ReadNum(numFolders));

  {
    CStreamSwitch streamSwitch;
    RINOK(streamSwitch.Set(this, dataVector));
    folders.Clear();
    folders.Reserve((UInt32)numFolders);
    for(CNum i = 0; i < numFolders; i++)
    {
      folders.Add(CFolder());
      RINOK(GetNextFolderItem(folders.Back()));
    }
  }

  RINOK(WaitAttribute(NID::kCodersUnPackSize));

  CNum i;
  for(i = 0; i < numFolders; i++)
  {
    CFolder &folder = folders[i];
    CNum numOutStreams = folder.GetNumOutStreams();
    folder.UnPackSizes.Reserve(numOutStreams);
    for(CNum j = 0; j < numOutStreams; j++)
    {
      UInt64 unPackSize;
      RINOK(ReadNumber(unPackSize));
      folder.UnPackSizes.Add(unPackSize);
    }
  }

  while(true)
  {
    UInt64 type;
    RINOK(ReadID(type));
    if (type == NID::kEnd)
      return S_OK;
    if (type == NID::kCRC)
    {
      CRecordVector<bool> crcsDefined;
      CRecordVector<UInt32> crcs;
      RINOK(ReadHashDigests(numFolders, crcsDefined, crcs)); 
      for(i = 0; i < numFolders; i++)
      {
        CFolder &folder = folders[i];
        folder.UnPackCRCDefined = crcsDefined[i];
        folder.UnPackCRC = crcs[i];
      }
      continue;
    }
    RINOK(SkeepData());
  }
}

HRESULT CInArchive::ReadSubStreamsInfo(
    const CObjectVector<CFolder> &folders,
    CRecordVector<CNum> &numUnPackStreamsInFolders,
    CRecordVector<UInt64> &unPackSizes,
    CRecordVector<bool> &digestsDefined, 
    CRecordVector<UInt32> &digests)
{
  numUnPackStreamsInFolders.Clear();
  numUnPackStreamsInFolders.Reserve(folders.Size());
  UInt64 type;
  while(true)
  {
    RINOK(ReadID(type));
    if (type == NID::kNumUnPackStream)
    {
      for(int i = 0; i < folders.Size(); i++)
      {
        CNum value;
        RINOK(ReadNum(value));
        numUnPackStreamsInFolders.Add(value);
      }
      continue;
    }
    if (type == NID::kCRC || type == NID::kSize)
      break;
    if (type == NID::kEnd)
      break;
    RINOK(SkeepData());
  }

  if (numUnPackStreamsInFolders.IsEmpty())
    for(int i = 0; i < folders.Size(); i++)
      numUnPackStreamsInFolders.Add(1);

  int i;
  for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
  {
    // v3.13 incorrectly worked with empty folders
    // v4.07: we check that folder is empty
    CNum numSubstreams = numUnPackStreamsInFolders[i];
    if (numSubstreams == 0)
      continue;
    UInt64 sum = 0;
    for (CNum j = 1; j < numSubstreams; j++)
    {
      UInt64 size;
      if (type == NID::kSize)
      {
        RINOK(ReadNumber(size));
        unPackSizes.Add(size);
        sum += size;
      }
    }
    unPackSizes.Add(folders[i].GetUnPackSize() - sum);
  }
  if (type == NID::kSize)
  {
    RINOK(ReadID(type));
  }

  int numDigests = 0;
  int numDigestsTotal = 0;
  for(i = 0; i < folders.Size(); i++)
  {
    CNum numSubstreams = numUnPackStreamsInFolders[i];
    if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
      numDigests += numSubstreams;
    numDigestsTotal += numSubstreams;
  }

  while(true)
  {
    if (type == NID::kCRC)
    {
      CRecordVector<bool> digestsDefined2; 
      CRecordVector<UInt32> digests2;
      RINOK(ReadHashDigests(numDigests, digestsDefined2, digests2));
      int digestIndex = 0;
      for (i = 0; i < folders.Size(); i++)
      {
        CNum numSubstreams = numUnPackStreamsInFolders[i];
        const CFolder &folder = folders[i];
        if (numSubstreams == 1 && folder.UnPackCRCDefined)
        {
          digestsDefined.Add(true);
          digests.Add(folder.UnPackCRC);
        }
        else
          for (CNum j = 0; j < numSubstreams; j++, digestIndex++)
          {
            digestsDefined.Add(digestsDefined2[digestIndex]);
            digests.Add(digests2[digestIndex]);
          }
      }
    }
    else if (type == NID::kEnd)
    {
      if (digestsDefined.IsEmpty())
      {
        digestsDefined.Clear();
        digests.Clear();
        for (int i = 0; i < numDigestsTotal; i++)
        {
          digestsDefined.Add(false);
          digests.Add(0);
        }
      }
      return S_OK;
    }
    else
    {
      RINOK(SkeepData());
    }
    RINOK(ReadID(type));
  }
}

HRESULT CInArchive::ReadStreamsInfo(
    const CObjectVector<CByteBuffer> *dataVector,
    UInt64 &dataOffset,
    CRecordVector<UInt64> &packSizes,
    CRecordVector<bool> &packCRCsDefined,
    CRecordVector<UInt32> &packCRCs,
    CObjectVector<CFolder> &folders,
    CRecordVector<CNum> &numUnPackStreamsInFolders,
    CRecordVector<UInt64> &unPackSizes,
    CRecordVector<bool> &digestsDefined, 
    CRecordVector<UInt32> &digests)
{
  while(true)
  {
    UInt64 type;
    RINOK(ReadID(type));
    switch(type)
    {
      case NID::kEnd:
        return S_OK;
      case NID::kPackInfo:
      {
        RINOK(ReadPackInfo(dataOffset, packSizes,
            packCRCsDefined, packCRCs));
        break;
      }
      case NID::kUnPackInfo:
      {
        RINOK(ReadUnPackInfo(dataVector, folders));
        break;
      }
      case NID::kSubStreamsInfo:
      {
        RINOK(ReadSubStreamsInfo(folders, numUnPackStreamsInFolders,
          unPackSizes, digestsDefined, digests));
        break;
      }
    }
  }
}

HRESULT CInArchive::ReadFileNames(CObjectVector<CFileItem> &files)
{
  for(int i = 0; i < files.Size(); i++)
  {
    UString &name = files[i].Name;
    name.Empty();
    while (true)
    {
      wchar_t c;
      RINOK(ReadWideCharLE(c));
      if (c == L'\0')
        break;
      name += c;
    }
  }
  return S_OK;
}

HRESULT CInArchive::ReadBoolVector(int numItems, CBoolVector &v)
{
  v.Clear();
  v.Reserve(numItems);
  Byte b;
  Byte mask = 0;
  for(int i = 0; i < numItems; i++)
  {
    if (mask == 0)
    {
      RINOK(ReadByte(b));
      mask = 0x80;
    }
    v.Add((b & mask) != 0);
    mask >>= 1;
  }
  return S_OK;
}

HRESULT CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
{
  Byte allAreDefined;
  RINOK(ReadByte(allAreDefined));
  if (allAreDefined == 0)
    return ReadBoolVector(numItems, v);
  v.Clear();
  v.Reserve(numItems);
  for (int i = 0; i < numItems; i++)
    v.Add(true);
  return S_OK;
}

HRESULT CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector,
    CObjectVector<CFileItem> &files, UInt64 type)
{
  CBoolVector boolVector;
  RINOK(ReadBoolVector2(files.Size(), boolVector))

  CStreamSwitch streamSwitch;
  RINOK(streamSwitch.Set(this, &dataVector));

  for(int i = 0; i < files.Size(); i++)
  {
    CFileItem &file = files[i];
    CArchiveFileTime fileTime;
    bool defined = boolVector[i];
    if (defined)
    {
      UInt32 low, high;
      RINOK(ReadUInt32(low));
      RINOK(ReadUInt32(high));
      fileTime.dwLowDateTime = low;
      fileTime.dwHighDateTime = high;
    }
    switch(type)
    {
      case NID::kCreationTime:
        file.IsCreationTimeDefined = defined;
        if (defined)
          file.CreationTime = fileTime;
        break;
      case NID::kLastWriteTime:
        file.IsLastWriteTimeDefined = defined;
        if (defined)
          file.LastWriteTime = fileTime;
        break;
      case NID::kLastAccessTime:
        file.IsLastAccessTimeDefined = defined;
        if (defined)
          file.LastAccessTime = fileTime;
        break;
    }
  }
  return S_OK;
}

HRESULT CInArchive::ReadAndDecodePackedStreams(UInt64 baseOffset, 
    UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
    #ifndef _NO_CRYPTO
    , ICryptoGetTextPassword *getTextPassword
    #endif
    )
{
  CRecordVector<UInt64> packSizes;
  CRecordVector<bool> packCRCsDefined;
  CRecordVector<UInt32> packCRCs;
  CObjectVector<CFolder> folders;
  
  CRecordVector<CNum> numUnPackStreamsInFolders;
  CRecordVector<UInt64> unPackSizes;
  CRecordVector<bool> digestsDefined;
  CRecordVector<UInt32> digests;
  
  RINOK(ReadStreamsInfo(NULL, 
    dataOffset,
    packSizes, 
    packCRCsDefined, 
    packCRCs, 
    folders,
    numUnPackStreamsInFolders,
    unPackSizes,
    digestsDefined, 
    digests));
  
  // database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
  
  CNum packIndex = 0;
  CDecoder decoder(false);
  UInt64 dataStartPos = baseOffset + dataOffset;
  for(int i = 0; i < folders.Size(); i++)
  {
    const CFolder &folder = folders[i];
    dataVector.Add(CByteBuffer());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -