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 + -
显示快捷键?