7zhandler.cpp

来自「由7-zip提供的压缩、解压缩程序」· C++ 代码 · 共 758 行 · 第 1/2 页

CPP
758
字号
// 7zHandler.cpp#include "StdAfx.h"#include "7zHandler.h"#include "7zProperties.h"#include "../../../Common/IntToString.h"#include "../../../Common/ComTry.h"#include "../../../Windows/Defs.h"#include "../Common/ItemNameUtils.h"#ifdef _7Z_VOL#include "../Common/MultiStream.h"#endif#ifdef __7Z_SET_PROPERTIES#ifdef EXTRACT_ONLY#include "../Common/ParseProperties.h"#endif#endifusing namespace NWindows;namespace NArchive {namespace N7z {CHandler::CHandler(){  #ifdef COMPRESS_MT  _numThreads = NWindows::NSystem::GetNumberOfProcessors();  #endif  #ifndef EXTRACT_ONLY  Init();  #endif  #ifndef EXCLUDE_COM  LoadMethodMap();  #endif}STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems){  COM_TRY_BEGIN  *numItems =   #ifdef _7Z_VOL  _refs.Size();  #else  *numItems = _database.Files.Size();  #endif  return S_OK;  COM_TRY_END}STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value){  value->vt = VT_EMPTY;  return S_OK;}#ifdef _SFXSTDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties){  return E_NOTIMPL;}STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,           BSTR *name, PROPID *propID, VARTYPE *varType){  return E_NOTIMPL;}#endifSTDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties){  *numProperties = 0;  return S_OK;}STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,           BSTR *name, PROPID *propID, VARTYPE *varType){  return E_NOTIMPL;}static void MySetFileTime(bool timeDefined, FILETIME unixTime,     NWindows::NCOM::CPropVariant &propVariant){  if (timeDefined)    propVariant = unixTime;}/*inline static wchar_t GetHex(Byte value){  return (value < 10) ? ('0' + value) : ('A' + (value - 10));}static UString ConvertBytesToHexString(const Byte *data, UInt32 size){  UString result;  for (UInt32 i = 0; i < size; i++)  {    Byte b = data[i];    result += GetHex(b >> 4);    result += GetHex(b & 0xF);  }  return result;}*/#ifndef _SFXstatic UString ConvertUInt32ToString(UInt32 value){  wchar_t buffer[32];  ConvertUInt64ToString(value, buffer);  return buffer;}static UString GetStringForSizeValue(UInt32 value){  for (int i = 31; i >= 0; i--)    if ((UInt32(1) << i) == value)      return ConvertUInt32ToString(i);  UString result;  if (value % (1 << 20) == 0)  {    result += ConvertUInt32ToString(value >> 20);    result += L"m";  }  else if (value % (1 << 10) == 0)  {    result += ConvertUInt32ToString(value >> 10);    result += L"k";  }  else  {    result += ConvertUInt32ToString(value);    result += L"b";  }  return result;}static CMethodID k_Copy  = { { 0x0 }, 1 };static CMethodID k_LZMA  = { { 0x3, 0x1, 0x1 }, 3 };static CMethodID k_BCJ   = { { 0x3, 0x3, 0x1, 0x3 }, 4 };static CMethodID k_BCJ2  = { { 0x3, 0x3, 0x1, 0x1B }, 4 };static CMethodID k_PPMD  = { { 0x3, 0x4, 0x1 }, 3 };static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };static inline char GetHex(Byte value){  return (value < 10) ? ('0' + value) : ('A' + (value - 10));}static inline UString GetHex2(Byte value){  UString result;  result += GetHex(value >> 4);  result += GetHex(value & 0xF);  return result;}#endifstatic inline UInt32 GetUInt32FromMemLE(const Byte *p){  return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);}STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID,  PROPVARIANT *value){  COM_TRY_BEGIN  NWindows::NCOM::CPropVariant propVariant;    /*  const CRef2 &ref2 = _refs[index];  if (ref2.Refs.IsEmpty())    return E_FAIL;  const CRef &ref = ref2.Refs.Front();  */    #ifdef _7Z_VOL  const CRef &ref = _refs[index];  const CVolume &volume = _volumes[ref.VolumeIndex];  const CArchiveDatabaseEx &_database = volume.Database;  UInt32 index2 = ref.ItemIndex;  const CFileItem &item = _database.Files[index2];  #else  const CFileItem &item = _database.Files[index];  UInt32 index2 = index;  #endif  switch(propID)  {    case kpidPath:    {      if (!item.Name.IsEmpty())        propVariant = NItemName::GetOSName(item.Name);      break;    }    case kpidIsFolder:      propVariant = item.IsDirectory;      break;    case kpidSize:    {      propVariant = item.UnPackSize;      // propVariant = ref2.UnPackSize;      break;    }    case kpidPosition:    {      /*      if (ref2.Refs.Size() > 1)        propVariant = ref2.StartPos;      else      */        if (item.IsStartPosDefined)          propVariant = item.StartPos;      break;    }    case kpidPackedSize:    {      // propVariant = ref2.PackSize;      {        CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];        if (folderIndex != kNumNoIndex)        {          if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)            propVariant = _database.GetFolderFullPackSize(folderIndex);          /*          else            propVariant = UInt64(0);          */        }        else          propVariant = UInt64(0);      }      break;    }    case kpidLastAccessTime:      MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, propVariant);      break;    case kpidCreationTime:      MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, propVariant);      break;    case kpidLastWriteTime:      MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, propVariant);      break;    case kpidAttributes:      if (item.AreAttributesDefined)        propVariant = item.Attributes;      break;    case kpidCRC:      if (item.IsFileCRCDefined)        propVariant = item.FileCRC;      break;    #ifndef _SFX    case kpidMethod:      {        CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];        if (folderIndex != kNumNoIndex)        {          const CFolder &folderInfo = _database.Folders[folderIndex];          UString methodsString;          for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)          {            const CCoderInfo &coderInfo = folderInfo.Coders[i];            if (!methodsString.IsEmpty())              methodsString += L' ';            CMethodInfo methodInfo;            bool methodIsKnown;            for (int j = 0; j < coderInfo.AltCoders.Size(); j++)            {              if (j > 0)                methodsString += L"|";              const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders[j];              UString methodName;              #ifdef NO_REGISTRY              methodIsKnown = true;              if (altCoderInfo.MethodID == k_Copy)                methodName = L"Copy";                          else if (altCoderInfo.MethodID == k_LZMA)                methodName = L"LZMA";              else if (altCoderInfo.MethodID == k_BCJ)                methodName = L"BCJ";              else if (altCoderInfo.MethodID == k_BCJ2)                methodName = L"BCJ2";              else if (altCoderInfo.MethodID == k_PPMD)                methodName = L"PPMD";              else if (altCoderInfo.MethodID == k_Deflate)                methodName = L"Deflate";              else if (altCoderInfo.MethodID == k_BZip2)                methodName = L"BZip2";              else                methodIsKnown = false;                            #else                          methodIsKnown = GetMethodInfo(                altCoderInfo.MethodID, methodInfo);              methodName = methodInfo.Name;                            #endif              if (methodIsKnown)              {                methodsString += methodName;                if (altCoderInfo.MethodID == k_LZMA)                {                  if (altCoderInfo.Properties.GetCapacity() >= 5)                  {                    methodsString += L":";                    UInt32 dicSize = GetUInt32FromMemLE(                      ((const Byte *)altCoderInfo.Properties + 1));                    methodsString += GetStringForSizeValue(dicSize);                  }                }                else if (altCoderInfo.MethodID == k_PPMD)                {                  if (altCoderInfo.Properties.GetCapacity() >= 5)                  {                    Byte order = *(const Byte *)altCoderInfo.Properties;                    methodsString += L":o";                    methodsString += ConvertUInt32ToString(order);                    methodsString += L":mem";                    UInt32 dicSize = GetUInt32FromMemLE(                      ((const Byte *)altCoderInfo.Properties + 1));                    methodsString += GetStringForSizeValue(dicSize);                  }                }                else                {                  if (altCoderInfo.Properties.GetCapacity() > 0)                  {                    methodsString += L":[";                    for (size_t bi = 0; bi < altCoderInfo.Properties.GetCapacity(); bi++)                    {                      if (bi > 2 && bi + 1 < altCoderInfo.Properties.GetCapacity())                      {                        methodsString += L"..";                        break;                      }                      else                        methodsString += GetHex2(altCoderInfo.Properties[bi]);                    }                    methodsString += L"]";                  }                }              }              else              {                methodsString += altCoderInfo.MethodID.ConvertToString();              }            }          }          propVariant = methodsString;        }      }      break;    case kpidBlock:      {        CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];        if (folderIndex != kNumNoIndex)          propVariant = (UInt32)folderIndex;      }      break;    case kpidPackedSize0:    case kpidPackedSize1:    case kpidPackedSize2:

⌨️ 快捷键说明

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