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

📄 agent.cpp

📁 7-Zip 是一款号称有着现今最高压缩比的压缩软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:

static const UInt32 kNumFolderProps = sizeof(kFolderProps) / sizeof(kFolderProps[0]);

STDMETHODIMP CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
{
  COM_TRY_BEGIN
  NWindows::NCOM::CPropVariant prop;
  switch(propID)
  {
    case kpidSize:         prop = _proxyFolderItem->Size; break;
    case kpidPackSize:     prop = _proxyFolderItem->PackSize; break;
    case kpidNumSubDirs:   prop = _proxyFolderItem->NumSubFolders; break;
    case kpidNumSubFiles:  prop = _proxyFolderItem->NumSubFiles; break;
    case kpidName:         prop = _proxyFolderItem->Name; break;
    case kpidPath:         prop = _proxyFolderItem->GetFullPathPrefix(); break;
    case kpidType: prop = UString(L"7-Zip.") + _agentSpec->ArchiveType; break;
    case kpidCRC: if (_proxyFolderItem->CrcIsDefined) prop = _proxyFolderItem->Crc; break;
  }
  prop.Detach(value);
  return S_OK;
  COM_TRY_END
}

STDMETHODIMP CAgentFolder::GetNumberOfFolderProperties(UInt32 *numProperties)
{
  *numProperties = kNumFolderProps;
  return S_OK;
}

STDMETHODIMP CAgentFolder::GetFolderPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
{
  // if (index < kNumFolderProps)
  {
    const STATPROPSTG &srcItem = kFolderProps[index];
    *propID = srcItem.propid;
    *varType = srcItem.vt;
    *name = 0;
    return S_OK;
  }
}

STDMETHODIMP CAgentFolder::GetFolderArchiveProperties(IFolderArchiveProperties **object)
{
  CMyComPtr<IFolderArchiveProperties> temp = _agentSpec;
  *object = temp.Detach();
  return S_OK;
}

#ifdef NEW_FOLDER_INTERFACE

STDMETHODIMP CAgentFolder::SetFlatMode(Int32 flatMode)
{
  _flatMode = IntToBool(flatMode);
  return S_OK;
}

#endif

void CAgentFolder::GetRealIndices(const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const
{
  if (!_flatMode)
  {
    _proxyFolderItem->GetRealIndices(indices, numItems, realIndices);
    return;
  }
  realIndices.Clear();
  for(UInt32 i = 0; i < numItems; i++)
  {
    const CProxyItem &item = _items[indices[i]];
    const CProxyFolder *folder = item.Folder;
    UInt32 realIndex = item.Index;
    if (realIndex < (UInt32)folder->Folders.Size())
      continue;
    realIndices.Add(folder->Files[realIndex - folder->Folders.Size()].Index);
  }
  HeapSort(&realIndices.Front(), realIndices.Size());
}

STDMETHODIMP CAgentFolder::Extract(const UInt32 *indices,
    UInt32 numItems,
    NExtract::NPathMode::EEnum pathMode,
    NExtract::NOverwriteMode::EEnum overwriteMode,
    const wchar_t *path,
    INT32 testMode,
    IFolderArchiveExtractCallback *extractCallback2)
{
  COM_TRY_BEGIN
  CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
  CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
  UStringVector pathParts;
  CProxyFolder *currentProxyFolder = _proxyFolderItem;
  while (currentProxyFolder->Parent)
  {
    pathParts.Insert(0, currentProxyFolder->Name);
    currentProxyFolder = currentProxyFolder->Parent;
  }
  
  /*
  if (_flatMode)
    pathMode = NExtract::NPathMode::kNoPathnames;
  */

  extractCallbackSpec->InitForMulti(false, pathMode, overwriteMode);

  extractCallbackSpec->Init(_agentSpec->GetArchive(),
      extractCallback2,
      false,
      (path ? path : L""),
      pathParts,
      _agentSpec->DefaultName,
      _agentSpec->DefaultTime,
      _agentSpec->DefaultAttrib,
      (UInt64)(Int64)-1
      // ,_agentSpec->_srcDirectoryPrefix
      );
  CUIntVector realIndices;
  GetRealIndices(indices, numItems, realIndices);
  return _agentSpec->GetArchive()->Extract(&realIndices.Front(),
      realIndices.Size(), testMode, extractCallback);
  COM_TRY_END
}

/////////////////////////////////////////
// CAgent

CAgent::CAgent():
  _proxyArchive(NULL),
  _codecs(0)
{
}

CAgent::~CAgent()
{
  if (_proxyArchive != NULL)
    delete _proxyArchive;
}

STDMETHODIMP CAgent::Open(
    const wchar_t *filePath,
    BSTR *archiveType,
    // CLSID *clsIDResult,
    IArchiveOpenCallback *openArchiveCallback)
{
  COM_TRY_BEGIN
  _archiveFilePath = filePath;
  NFile::NFind::CFileInfoW fileInfo;
  if (!NFile::NFind::FindFile(_archiveFilePath, fileInfo))
    return ::GetLastError();
  if (fileInfo.IsDir())
    return E_FAIL;
  CArcInfoEx archiverInfo0, archiverInfo1;

  _compressCodecsInfo.Release();
  _codecs = new CCodecs;
  _compressCodecsInfo = _codecs;
  RINOK(_codecs->Load());

  RINOK(OpenArchive(_codecs, CIntVector(), _archiveFilePath, _archiveLink, openArchiveCallback));
  // _archive = _archiveLink.GetArchive();
  DefaultName = _archiveLink.GetDefaultItemName();
  const CArcInfoEx &ai = _codecs->Formats[_archiveLink.GetArchiverIndex()];

  DefaultTime = fileInfo.MTime;
  DefaultAttrib = fileInfo.Attrib;
  ArchiveType = ai.Name;
  if (archiveType == 0)
    return S_OK;
  return StringToBstr(ArchiveType, archiveType);
  COM_TRY_END
}

STDMETHODIMP CAgent::ReOpen(IArchiveOpenCallback *openArchiveCallback)
{
  COM_TRY_BEGIN
  if (_proxyArchive != NULL)
  {
    delete _proxyArchive;
    _proxyArchive = NULL;
  }
  RINOK(ReOpenArchive(_codecs, _archiveLink, _archiveFilePath, openArchiveCallback));
  return ReadItems();
  COM_TRY_END
}

STDMETHODIMP CAgent::Close()
{
  COM_TRY_BEGIN
  RINOK(_archiveLink.Close());
  if (_archiveLink.GetNumLevels() > 1)
  {
    // return S_OK;
  }
  // _archive->Close();
  return S_OK;
  COM_TRY_END
}

/*
STDMETHODIMP CAgent::EnumProperties(IEnumSTATPROPSTG **EnumProperties)
{
  return _archive->EnumProperties(EnumProperties);
}
*/

HRESULT CAgent::ReadItems()
{
  if (_proxyArchive != NULL)
    return S_OK;
  _proxyArchive = new CProxyArchive();
  return _proxyArchive->Load(GetArchive(),
      DefaultName,
      // _defaultTime,
      // _defaultAttrib,
      NULL);
}

STDMETHODIMP CAgent::BindToRootFolder(IFolderFolder **resultFolder)
{
  COM_TRY_BEGIN
  RINOK(ReadItems());
  CAgentFolder *folderSpec = new CAgentFolder;
  CMyComPtr<IFolderFolder> rootFolder = folderSpec;
  folderSpec->Init(_proxyArchive, &_proxyArchive->RootFolder, NULL, this);
  *resultFolder = rootFolder.Detach();
  return S_OK;
  COM_TRY_END
}


STDMETHODIMP CAgent::Extract(
    NExtract::NPathMode::EEnum pathMode,
    NExtract::NOverwriteMode::EEnum overwriteMode,
    const wchar_t *path,
    INT32 testMode,
    IFolderArchiveExtractCallback *extractCallback2)
{
  COM_TRY_BEGIN
  CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
  CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
  extractCallbackSpec->InitForMulti(false, pathMode, overwriteMode);
  extractCallbackSpec->Init(GetArchive(),
      extractCallback2,
      false,
      path,
      UStringVector(),
      DefaultName,
      DefaultTime,
      DefaultAttrib,
      (UInt64)(Int64)-1
      // ,_srcDirectoryPrefix
      );
  return GetArchive()->Extract(0, (UInt32)(Int32)-1, testMode, extractCallback);
  COM_TRY_END
}

STDMETHODIMP CAgent::GetNumberOfProperties(UInt32 *numProperties)
{
  COM_TRY_BEGIN
  return GetArchive()->GetNumberOfProperties(numProperties);
  COM_TRY_END
}

STDMETHODIMP CAgent::GetPropertyInfo(UInt32 index,
      BSTR *name, PROPID *propID, VARTYPE *varType)
{
  COM_TRY_BEGIN
  RINOK(GetArchive()->GetPropertyInfo(index, name, propID, varType));
  if (*propID == kpidPath)
    *propID = kpidName;
  return S_OK;
  COM_TRY_END
}

STDMETHODIMP CAgent::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
  COM_TRY_BEGIN
  return GetArchive()->GetArchiveProperty(propID, value);
  COM_TRY_END
}

STDMETHODIMP CAgent::GetNumberOfArchiveProperties(UInt32 *numProperties)
{
  COM_TRY_BEGIN
  return GetArchive()->GetNumberOfArchiveProperties(numProperties);
  COM_TRY_END
}

STDMETHODIMP CAgent::GetArchivePropertyInfo(UInt32 index,
      BSTR *name, PROPID *propID, VARTYPE *varType)
{
  COM_TRY_BEGIN
  return GetArchive()->GetArchivePropertyInfo(index,
      name, propID, varType);
  COM_TRY_END
}

⌨️ 快捷键说明

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