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

📄 compressengine.cpp

📁 7-Zip 3.11的源码
💻 CPP
字号:
// CompressEngine.h

#include "StdAfx.h"

#include "ProxyHandler.h"
#include "CompressEngine.h"
#include "UpdateEngine.h"

#include "../../Archiver/Common/CompressEngineCommon.h"
#include "../../Archiver/Common/OpenEngine2.h"
#include "../../Archiver/Common/UpdateProducer.h"
#include "../../Archiver/Common/UpdateUtils.h"

#include "Windows/File/Name.h"
#include "Windows/File/Find.h"
#include "Windows/File/Directory.h"
#include "Windows/PropVariant.h"
#include "Windows/Error.h"

#include "../../../WinWrappers/PropVariantConversions.h"

// #include "CompressDialog.h"

#include "Common/StringConvert.h"
// #include "ArchiveStyleDirItemInfo.h"

#include "Interface/FileStreams.h"

#include "Messages.h"
#include "Far/FarUtils.h"
// #include "ZipViewUtils.h"

using namespace NWindows;
using namespace NFile;
using namespace NName;
using namespace NCOM;

using namespace NFar;
using namespace NUpdateArchive;

#define RETURN_IF_NOT_S_OK(x) { HRESULT aResult = (x); if(aResult != S_OK) return aResult; }

static LPCTSTR kTempArcivePrefix = "7zi";

static void GetFileTime(CProxyHandler *aProxyHandler, LPCITEMIDLIST anItemIDList, 
    FILETIME &aFileTime)
{
  CPropVariant aProperty;
  aProxyHandler->GetPropertyValue(anItemIDList, kaipidLastWriteTime, &aProperty);
  if (aProperty.vt == VT_FILETIME)
    aFileTime = aProperty.filetime;
  else if (aProperty.vt == VT_EMPTY)
    aFileTime = aProxyHandler->m_ArchiveFileInfo.LastWriteTime;
  else
    throw 4190407;
}

void EnumerateInArchiveItems(CProxyHandler *aProxyHandler, 
    const CArchiveFolderItem &anItem, const UString &aPrefix,
    CArchiveItemInfoVector &anArchiveItems)
{
  for(int i = 0; i < anItem.m_FileSubItems.Size(); i++)
  {
    const CArchiveFolderFileItem &aFileItem = anItem.m_FileSubItems[i];
    CArchiveItemInfo anItemInfo;

    GetFileTime(aProxyHandler, aFileItem.m_Properties, anItemInfo.LastWriteTime);

    CPropVariant aProperty;
    aProxyHandler->GetPropertyValue(aFileItem.m_Properties, kaipidSize, &aProperty);
    if (anItemInfo.SizeIsDefined = (aProperty.vt != VT_EMPTY))
      anItemInfo.Size = ConvertPropVariantToUINT64(aProperty);
    anItemInfo.IsDirectory = false;
    anItemInfo.Name = aPrefix + aFileItem.m_Name;
    anItemInfo.Censored = true; // test it
    anItemInfo.IndexInServer = aProxyHandler->GetHandlerItemIndex(aFileItem.m_Properties);
    anArchiveItems.Add(anItemInfo);
  }
  for(i = 0; i < anItem.m_DirSubItems.Size(); i++)
  {
    const CArchiveFolderItem &aDirItem = anItem.m_DirSubItems[i];
    if(!aDirItem.m_IsLeaf)
      continue;
    CArchiveItemInfo anItemInfo;
    GetFileTime(aProxyHandler, aDirItem.m_Properties, anItemInfo.LastWriteTime);
    anItemInfo.IsDirectory = true;
    anItemInfo.SizeIsDefined = false;
    anItemInfo.Name = aPrefix + aDirItem.m_Name;
    anItemInfo.Censored = true; // test it
    anItemInfo.IndexInServer = aProxyHandler->GetHandlerItemIndex(
        aDirItem.m_Properties);
    anArchiveItems.Add(anItemInfo);
    EnumerateInArchiveItems(aProxyHandler, aDirItem, anItemInfo.Name + 
        wchar_t(kDirDelimiter), anArchiveItems);
  }
}


static const char *kExtension = _T(".zip");


HRESULT Compress(const CSysStringVector &aFileNames, 
    const UString &anArchiveNamePrefix, 
    const CActionSet &anActionSet, CProxyHandler *aProxyHandler,
    const CLSID &aClassID, bool aStoreMode, bool aMaximizeRatioMode,
    CSysString &anArchiveName, CProgressBox *aProgressBox)
{
  CComPtr<IOutArchiveHandler> anOutArchive;
  CArchiveItemInfoVector anArchiveItems;
  if(aProxyHandler != NULL)
  {
    HRESULT aResult = aProxyHandler->m_ArchiveHandler.QueryInterface(&anOutArchive);
    if(aResult != S_OK)
    {
      g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
      return E_FAIL;
    }
    EnumerateInArchiveItems(aProxyHandler, 
      aProxyHandler->m_FolderItemHead,  L"", anArchiveItems);
  }
  else
  {
    HRESULT aResult = anOutArchive.CoCreateInstance(aClassID);
    if (aResult != S_OK)
    {
      g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
      return E_FAIL;
    }
  }
  CArchiveStyleDirItemInfoVector aDirItems;

  EnumerateItems(aFileNames, anArchiveNamePrefix, aDirItems, CP_OEMCP);
  
  CUpdatePairInfoVector anUpdatePairs;

  NFileTimeType::EEnum aFileTimeType;
  UINT32 aValue;
  RETURN_IF_NOT_S_OK(anOutArchive->GetFileTimeType(&aValue));

  switch(aValue)
  {
    case NFileTimeType::kWindows:
    case NFileTimeType::kDOS:
    case NFileTimeType::kUnix:
      aFileTimeType = NFileTimeType::EEnum(aValue);
      break;
    default:
      return E_FAIL;
  }

  GetUpdatePairInfoList(aDirItems, anArchiveItems, aFileTimeType, anUpdatePairs);
  
  CUpdatePairInfo2Vector anOperationChain;
  UpdateProduce(aDirItems, anArchiveItems, anUpdatePairs, anActionSet,
      anOperationChain);
  
  CComObjectNoLock<CUpdateCallBackImp> *anUpdateCallBackSpec =
    new CComObjectNoLock<CUpdateCallBackImp>;
  CComPtr<IUpdateCallBack> anUpdateCallBack(anUpdateCallBackSpec );
  
  anUpdateCallBackSpec->Init(&aDirItems, &anArchiveItems, &anOperationChain,
      aProgressBox);
  
  CComObjectNoLock<COutFileStream> *anOutStreamSpec =
    new CComObjectNoLock<COutFileStream>;
  CComPtr<IOutStream> anOutStream(anOutStreamSpec);

  {
    CSysString aResultPath;
    int aPos;
    if(! NFile::NDirectory::MyGetFullPathName(anArchiveName, aResultPath, aPos))
      throw 141716;
    NFile::NDirectory::CreateComplexDirectory(aResultPath.Left(aPos));
  }
  if (!anOutStreamSpec->Open(anArchiveName))
  {
    ShowLastErrorMessage();
    return E_FAIL;
  }
  
  HRESULT aResult = anOutArchive->UpdateItems(anOutStream, anOperationChain.Size(),
     BoolToMyBool(aStoreMode), BoolToMyBool(aMaximizeRatioMode), anUpdateCallBack);
  return aResult;
}


// The returned string ends with a backslash


/*

void CompressArchive(const CSysStringVector &aFileNames)
{
  if (aFileNames.Size() == 0)
    return;
  CSysString aResultPath;
  {
    CParsedPath aParsedPath;
    aParsedPath.ParsePath(aFileNames.Front());
    if(aParsedPath.PathParts.Size() == 0)
      return; // Error
    if (aFileNames.Size() == 1 || aParsedPath.PathParts.Size() == 1)
    {
      CSysString aPureName, aDot, anExtension;
      SplitNameToPureNameAndExtension(aParsedPath.PathParts.Back(), 
        aPureName, aDot, anExtension);
      // aParsedPath.PathParts.Back() = aPureName;
      // aResultPath = aParsedPath.MergePath();
      aResultPath = aPureName;
    }
    else
    {
      aParsedPath.PathParts.DeleteBack();
      // aResultPath = aParsedPath.MergePath();
      // aResultPath += NFile::NName::kDirDelimiter;
      // aResultPath += aParsedPath.PathParts.Back();
      aResultPath = aParsedPath.PathParts.Back();
    }
    aResultPath += kExtension;
  }
  CSysString aCurrentDir;
  {
    CParsedPath aParsedPath;
    aParsedPath.ParsePath(aFileNames.Front());
    aParsedPath.PathParts.DeleteBack();
    aCurrentDir = aParsedPath.MergePath();
    if (aParsedPath.PathParts.Size() > 0)
      aCurrentDir += NFile::NName::kDirDelimiter;
  }


  CCompressDialog aDialog;
  
  
  
  CZipRegistryManager aZipRegistryManager;
  aDialog.m_ZipRegistryManager = &aZipRegistryManager;

  NZipRootRegistry::CArchiverInfoVector anArchiverInfoList;
  NZipRootRegistry::ReadArchiverInfoList(anArchiverInfoList);
  aDialog.m_ArchiverInfoList.Clear();
  for(int i = 0; i < anArchiverInfoList.Size(); i++)
  {
    NZipRootRegistry::CArchiverInfo anArchiverInfo = anArchiverInfoList[i];
    if (anArchiverInfo.UpdateEnabled)
      aDialog.m_ArchiverInfoList.Add(anArchiverInfo);
  }
  if(aDialog.m_ArchiverInfoList.Size() == 0)
  {
    AfxMessageBox("No Update Engines");
    return;
  }

  aDialog.m_Info.ArchiveName = aResultPath;
  aDialog.m_Info.CurrentDirPrefix = aCurrentDir;

  if(aDialog.DoModal() != IDOK)
    return;

  CSysString anArcPath;
  if (!aDialog.m_Info.GetFullPathName(anArcPath))
  {
    AfxMessageBox("Incorrect archive path");;
    return;
  }
  const CActionSet *anActionSet;
  switch(aDialog.m_Info.UpdateMode)
  {
    case NCompressDialog::NUpdateMode::kAdd:
      anActionSet = &kAddActionSet;
      break;
    case NCompressDialog::NUpdateMode::kUpdate:
      anActionSet = &kUpdateActionSet;
      break;
    case NCompressDialog::NUpdateMode::kFresh:
      anActionSet = &kFreshActionSet;
      break;
    case NCompressDialog::NUpdateMode::kSynchronize:
      anActionSet = &kSynchronizeActionSet;
      break;
    default:
      throw 1091756;
  }


  NZipSettings::NWorkDir::CInfo aWorkDirInfo;
  aZipRegistryManager.ReadWorkDirInfo(aWorkDirInfo);
  CSysString aWorkDir = GetWorkDir(aWorkDirInfo, anArcPath);
  NFile::NDirectory::CreateComplexDirectory(aWorkDir);

  NFile::NDirectory::CTempFile aTempFile;
  CSysString aTempFileName;
  if (aTempFile.Create(aWorkDir, kTempArcivePrefix, aTempFileName) == 0)
    return;

  CProxyHandler *aProxyHandler;
  NFind::CFileInfo aFileInfo;
  if(NFind::FindFile(anArcPath, aFileInfo))
  {
    if (aFileInfo.IsDirectory())
    {
      CString aMessage;
      AfxFormatString1(aMessage, IDS_CANT_UPDATE_ARCHIVE, anArcPath);
      AfxMessageBox(aMessage);
      return;
    }
    bool aHandlerIsNew;
    if (!g_HandlersManager.GetProxyHandler(anArcPath, &aProxyHandler, aHandlerIsNew))
    {
      CString aMessage;
      AfxFormatString1(aMessage, IDS_CANT_UPDATE_ARCHIVE, anArcPath);
      AfxMessageBox(aMessage);
      return;
    }
  }
  else
    aProxyHandler = NULL;


  HRESULT aResult = Compress(aFileNames, *anActionSet, aProxyHandler, 
      aDialog.m_ArchiverInfoList[aDialog.m_Info.ArchiverInfoIndex].ClassID,
      aDialog.m_Info.Method == NCompressDialog::NMethod::kStore,
      aDialog.m_Info.Method == NCompressDialog::NMethod::kMaximum,
        aTempFileName);
  if (aResult != S_OK)
  {
    ShowErrorMessage(aResult);
    return;
  }
  if(aProxyHandler != 0) // Update
  {
    if (!NFile::NDirectory::DeleteFileAlways(anArcPath))
    {
      ShowLastErrorMessage();
      return;
    }
  }
  aTempFile.DisableDeleting();
  if (!MoveFile(aTempFileName, anArcPath))
  {
    ShowLastErrorMessage();
    return;
  }
}
*/


⌨️ 快捷键说明

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