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

📄 ziphandlerout.cpp

📁 由7-zip提供的压缩、解压缩程序
💻 CPP
字号:
// Zip/HandlerOut.cpp#include "StdAfx.h"#include "ZipHandler.h"#include "ZipUpdate.h"#include "Common/StringConvert.h"#include "Common/ComTry.h"#include "Common/StringToInt.h"#include "Windows/PropVariant.h"#include "Windows/Time.h"#include "../../IPassword.h"#include "../Common/ItemNameUtils.h"#include "../Common/ParseProperties.h"using namespace NWindows;using namespace NCOM;using namespace NTime;namespace NArchive {namespace NZip {static const UInt32 kDeflateNumPassesX1  = 1;static const UInt32 kDeflateNumPassesX7  = 3;static const UInt32 kDeflateNumPassesX9  = 10;static const UInt32 kNumFastBytesX1 = 32;static const UInt32 kNumFastBytesX7 = 64;static const UInt32 kNumFastBytesX9 = 128;static const UInt32 kBZip2NumPassesX1 = 1;static const UInt32 kBZip2NumPassesX7 = 2;static const UInt32 kBZip2NumPassesX9 = 7;static const UInt32 kBZip2DicSizeX1 = 100000;static const UInt32 kBZip2DicSizeX3 = 500000;static const UInt32 kBZip2DicSizeX5 = 900000;STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType){  *timeType = NFileTimeType::kDOS;  return S_OK;}STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,    IArchiveUpdateCallback *updateCallback){  COM_TRY_BEGIN  CObjectVector<CUpdateItem> updateItems;  for(UInt32 i = 0; i < numItems; i++)  {    CUpdateItem updateItem;    Int32 newData;    Int32 newProperties;    UInt32 indexInArchive;    if (!updateCallback)      return E_FAIL;    RINOK(updateCallback->GetUpdateItemInfo(i,        &newData, // 1 - compress 0 - copy        &newProperties,        &indexInArchive));    updateItem.NewProperties = IntToBool(newProperties);    updateItem.NewData = IntToBool(newData);    updateItem.IndexInArchive = indexInArchive;    updateItem.IndexInClient = i;    // bool existInArchive = (indexInArchive != UInt32(-1));    if (IntToBool(newProperties))    {      FILETIME utcFileTime;      UString name;      bool isDirectoryStatusDefined;      {        NCOM::CPropVariant propVariant;        RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));        if (propVariant.vt == VT_EMPTY)          updateItem.Attributes = 0;        else if (propVariant.vt != VT_UI4)          return E_INVALIDARG;        else          updateItem.Attributes = propVariant.ulVal;      }      {        NCOM::CPropVariant propVariant;        RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &propVariant));        if (propVariant.vt != VT_FILETIME)          return E_INVALIDARG;        utcFileTime = propVariant.filetime;      }      {        NCOM::CPropVariant propVariant;        RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));        if (propVariant.vt == VT_EMPTY)          name.Empty();        else if (propVariant.vt != VT_BSTR)          return E_INVALIDARG;        else          name = propVariant.bstrVal;      }      {        NCOM::CPropVariant propVariant;        RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant));        if (propVariant.vt == VT_EMPTY)          isDirectoryStatusDefined = false;        else if (propVariant.vt != VT_BOOL)          return E_INVALIDARG;        else        {          updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE);          isDirectoryStatusDefined = true;        }      }      FILETIME localFileTime;      if(!FileTimeToLocalFileTime(&utcFileTime, &localFileTime))        return E_INVALIDARG;      if(!FileTimeToDosTime(localFileTime, updateItem.Time))      {        // return E_INVALIDARG;      }      if (!isDirectoryStatusDefined)        updateItem.IsDirectory = ((updateItem.Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0);      name = NItemName::MakeLegalName(name);      bool needSlash = updateItem.IsDirectory;      const wchar_t kSlash = L'/';      if (!name.IsEmpty())      {        if (name[name.Length() - 1] == kSlash)        {          if (!updateItem.IsDirectory)            return E_INVALIDARG;          needSlash = false;        }      }      if (needSlash)        name += kSlash;      updateItem.Name = UnicodeStringToMultiByte(name, CP_OEMCP);      updateItem.IndexInClient = i;      /*      if(existInArchive)      {        const CItemEx &itemInfo = m_Items[indexInArchive];        // updateItem.Commented = itemInfo.IsCommented();        updateItem.Commented = false;        if(updateItem.Commented)        {          updateItem.CommentRange.Position = itemInfo.GetCommentPosition();          updateItem.CommentRange.Size  = itemInfo.CommentSize;        }      }      else        updateItem.Commented = false;      */    }    if (IntToBool(newData))    {      UInt64 size;      {        NCOM::CPropVariant propVariant;        RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));        if (propVariant.vt != VT_UI8)          return E_INVALIDARG;        size = propVariant.uhVal.QuadPart;      }      updateItem.Size = size;    }    updateItems.Add(updateItem);  }  CMyComPtr<ICryptoGetTextPassword2> getTextPassword;  if (!getTextPassword)  {    CMyComPtr<IArchiveUpdateCallback> udateCallBack2(updateCallback);    udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword);  }  CCompressionMethodMode options;  if (getTextPassword)  {    CMyComBSTR password;    Int32 passwordIsDefined;    RINOK(getTextPassword->CryptoGetTextPassword2(        &passwordIsDefined, &password));    if (options.PasswordIsDefined = IntToBool(passwordIsDefined))      options.Password = UnicodeStringToMultiByte((const wchar_t *)password, CP_OEMCP);  }  else    options.PasswordIsDefined = false;  int level = m_Level;  if (level < 0)    level = 5;    Byte mainMethod;  if (m_MainMethod < 0)    mainMethod = ((level == 0) ?        NFileHeader::NCompressionMethod::kStored :        NFileHeader::NCompressionMethod::kDeflated);  else    mainMethod = (Byte)m_MainMethod;  options.MethodSequence.Add(mainMethod);  if (mainMethod != NFileHeader::NCompressionMethod::kStored)    options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored);  bool isDeflate = (mainMethod == NFileHeader::NCompressionMethod::kDeflated) ||       (mainMethod == NFileHeader::NCompressionMethod::kDeflated64);  bool isBZip2 = (mainMethod == NFileHeader::NCompressionMethod::kBZip2);  options.NumPasses = m_NumPasses;  options.DicSize = m_DicSize;  options.NumFastBytes = m_NumFastBytes;  options.NumMatchFinderCycles = m_NumMatchFinderCycles;  options.NumMatchFinderCyclesDefined = m_NumMatchFinderCyclesDefined;  #ifdef COMPRESS_MT  options.NumThreads = _numThreads;  #endif  if (isDeflate)  {    if (options.NumPasses == 0xFFFFFFFF)      options.NumPasses = (level >= 9 ? kDeflateNumPassesX9 :                            (level >= 7 ? kDeflateNumPassesX7 :                                         kDeflateNumPassesX1));    if (options.NumFastBytes == 0xFFFFFFFF)      options.NumFastBytes = (level >= 9 ? kNumFastBytesX9 :                              (level >= 7 ? kNumFastBytesX7 :                                            kNumFastBytesX1));  }  if (isBZip2)  {    if (options.NumPasses == 0xFFFFFFFF)      options.NumPasses = (level >= 9 ? kBZip2NumPassesX9 :                           (level >= 7 ? kBZip2NumPassesX7 :                                          kBZip2NumPassesX1));    if (options.DicSize == 0xFFFFFFFF)      options.DicSize = (level >= 5 ? kBZip2DicSizeX5 :                         (level >= 3 ? kBZip2DicSizeX3 :                                       kBZip2DicSizeX1));  }  return Update(m_Items, updateItems, outStream,       m_ArchiveIsOpen ? &m_Archive : NULL, &options, updateCallback);  COM_TRY_END}STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties){  #ifdef COMPRESS_MT  const UInt32 numProcessors = NSystem::GetNumberOfProcessors();  _numThreads = numProcessors;  #endif  InitMethodProperties();  for (int i = 0; i < numProperties; i++)  {    UString name = UString(names[i]);    name.MakeUpper();    if (name.IsEmpty())      return E_INVALIDARG;    const PROPVARIANT &prop = values[i];    if (name[0] == L'X')    {      UInt32 level = 9;      RINOK(ParsePropValue(name.Mid(1), prop, level));      m_Level = level;      continue;    }    else if (name == L"M")    {      if (prop.vt == VT_BSTR)      {        UString valueString = prop.bstrVal;        valueString.MakeUpper();        if (valueString == L"COPY")          m_MainMethod = NFileHeader::NCompressionMethod::kStored;        else if (valueString == L"DEFLATE")          m_MainMethod = NFileHeader::NCompressionMethod::kDeflated;        else if (valueString == L"DEFLATE64")          m_MainMethod = NFileHeader::NCompressionMethod::kDeflated64;        else if (valueString == L"BZIP2")          m_MainMethod = NFileHeader::NCompressionMethod::kBZip2;        else           return E_INVALIDARG;      }      else if (prop.vt == VT_UI4)      {        switch(prop.ulVal)        {          case NFileHeader::NCompressionMethod::kStored:          case NFileHeader::NCompressionMethod::kDeflated:          case NFileHeader::NCompressionMethod::kDeflated64:          case NFileHeader::NCompressionMethod::kBZip2:            m_MainMethod = (Byte)prop.ulVal;            break;          default:            return E_INVALIDARG;        }      }      else        return E_INVALIDARG;    }    else if (name[0] == L'D')    {      UInt32 dicSize = kBZip2DicSizeX5;      RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize));      m_DicSize = dicSize;    }    else if (name.Left(4) == L"PASS")    {      UInt32 num = kDeflateNumPassesX9;      RINOK(ParsePropValue(name.Mid(4), prop, num));      m_NumPasses = num;    }    else if (name.Left(2) == L"FB")    {      UInt32 num = kNumFastBytesX9;      RINOK(ParsePropValue(name.Mid(2), prop, num));      m_NumFastBytes = num;    }    else if (name.Left(2) == L"MC")    {      UInt32 num = 0xFFFFFFFF;      RINOK(ParsePropValue(name.Mid(2), prop, num));      m_NumMatchFinderCycles = num;      m_NumMatchFinderCyclesDefined = true;    }    else if (name.Left(2) == L"MT")    {      #ifdef COMPRESS_MT      RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads));      #endif    }    else       return E_INVALIDARG;  }  return S_OK;}  }}

⌨️ 快捷键说明

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