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

📄 list.cpp

📁 一个7ZIP的解压源码。比较详细。里面含有四种语言的实现代码。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// List.cpp

#include "StdAfx.h"

#include "List.h"
#include "ConsoleClose.h"

#include "Common/StringConvert.h"
#include "Common/StdOutStream.h"
#include "Common/IntToString.h"
#include "Common/MyCom.h"

#include "Windows/PropVariant.h"
#include "Windows/Defs.h"
#include "Windows/PropVariantConversions.h"
#include "Windows/FileDir.h"

#include "../../Archive/IArchive.h"

#include "../Common/PropIDUtils.h"
#include "../Common/OpenArchive.h"

#include "OpenCallbackConsole.h"

using namespace NWindows;

struct CPropIdToName
{
  PROPID PropID;
  const wchar_t *Name;
};

static CPropIdToName kPropIdToName[] =  
{
  { kpidPath, L"Path" },
  { kpidName, L"Name" },
  { kpidIsFolder, L"Folder" }, 
  { kpidSize, L"Size" },
  { kpidPackedSize, L"Packed Size" },
  { kpidAttributes, L"Attributes" },
  { kpidCreationTime, L"Created" },
  { kpidLastAccessTime, L"Accessed" },
  { kpidLastWriteTime, L"Modified" },
  { kpidSolid, L"Solid" },
  { kpidCommented, L"Commented" },
  { kpidEncrypted, L"Encrypted" },
  { kpidSplitBefore, L"Split Before" },
  { kpidSplitAfter, L"Split After" },
  { kpidDictionarySize, L"Dictionary Size" },
  { kpidCRC, L"CRC" },
  { kpidType, L"Type" },
  { kpidIsAnti, L"Anti" },
  { kpidMethod, L"Method" },
  { kpidHostOS, L"Host OS" },
  { kpidFileSystem, L"File System" },
  { kpidUser, L"User" },
  { kpidGroup, L"Group" },
  { kpidBlock, L"Block" },
  { kpidComment, L"Comment" },
  { kpidPosition, L"Position" },
  { kpidPrefix, L"Prefix" },
  { kpidNumSubFolders, L"Folders" },
  { kpidNumSubFiles, L"Files" },
  { kpidUnpackVer, L"Version" },
  { kpidVolume, L"Volume" },
  { kpidIsVolume, L"Multivolume" },
  { kpidOffset, L"Offset" },
  { kpidLinks, L"Links" },
  { kpidNumBlocks, L"Blocks" },
  { kpidNumVolumes, L"Volumes" }
};

static const char kEmptyAttributeChar = '.';
static const char kDirectoryAttributeChar = 'D';
static const char kReadonlyAttributeChar  = 'R';
static const char kHiddenAttributeChar    = 'H';
static const char kSystemAttributeChar    = 'S';
static const char kArchiveAttributeChar   = 'A';

static const char *kListing = "Listing archive: ";
static const wchar_t *kFilesMessage = L"files";
static const wchar_t *kDirsMessage = L"folders";

static void GetAttributesString(DWORD wa, bool directory, char *s)
{
  s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || directory) ? 
      kDirectoryAttributeChar: kEmptyAttributeChar;
  s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0)? 
      kReadonlyAttributeChar: kEmptyAttributeChar;
  s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 
      kHiddenAttributeChar: kEmptyAttributeChar;
  s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 
      kSystemAttributeChar: kEmptyAttributeChar;
  s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 
      kArchiveAttributeChar: kEmptyAttributeChar;
  s[5] = '\0';
}

enum EAdjustment
{
  kLeft,
  kCenter,
  kRight
};

struct CFieldInfo
{
  PROPID PropID;
  UString Name;
  EAdjustment TitleAdjustment;
  EAdjustment TextAdjustment;
  int PrefixSpacesWidth;
  int Width;
};

struct CFieldInfoInit
{
  PROPID PropID;
  const wchar_t *Name;
  EAdjustment TitleAdjustment;
  EAdjustment TextAdjustment;
  int PrefixSpacesWidth;
  int Width;
};

CFieldInfoInit kStandardFieldTable[] = 
{
  { kpidLastWriteTime, L"   Date      Time", kLeft, kLeft, 0, 19 },
  { kpidAttributes, L"Attr", kRight, kCenter, 1, 5 },
  { kpidSize, L"Size", kRight, kRight, 1, 12 },
  { kpidPackedSize, L"Compressed", kRight, kRight, 1, 12 },
  { kpidPath, L"Name", kLeft, kLeft, 2, 24 }
};

void PrintSpaces(int numSpaces)
{
  for (int i = 0; i < numSpaces; i++)
    g_StdOut << ' ';
}

void PrintString(EAdjustment adjustment, int width, const UString &textString)
{
  const int numSpaces = width - textString.Length();
  int numLeftSpaces = 0;
  switch (adjustment)
  {
    case kLeft:
      numLeftSpaces = 0;
      break;
    case kCenter:
      numLeftSpaces = numSpaces / 2;
      break;
    case kRight:
      numLeftSpaces = numSpaces;
      break;
  }
  PrintSpaces(numLeftSpaces);
  g_StdOut << textString;
  PrintSpaces(numSpaces - numLeftSpaces);
}

class CFieldPrinter
{
  CObjectVector<CFieldInfo> _fields;
public:
  void Clear() { _fields.Clear(); }
  void Init(const CFieldInfoInit *standardFieldTable, int numItems);
  HRESULT Init(IInArchive *archive);
  void PrintTitle();
  void PrintTitleLines();
  HRESULT PrintItemInfo(IInArchive *archive, 
      const UString &defaultItemName,
      const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
      UInt32 index,
      bool techMode);
  HRESULT PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs, 
      const UInt64 *size, const UInt64 *compressedSize);
};

void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems)
{
  Clear();
  for (int i = 0; i < numItems; i++)
  {
    CFieldInfo fieldInfo;
    const CFieldInfoInit &fieldInfoInit = standardFieldTable[i];
    fieldInfo.PropID = fieldInfoInit.PropID;
    fieldInfo.Name = fieldInfoInit.Name;
    fieldInfo.TitleAdjustment = fieldInfoInit.TitleAdjustment;
    fieldInfo.TextAdjustment = fieldInfoInit.TextAdjustment;
    fieldInfo.PrefixSpacesWidth = fieldInfoInit.PrefixSpacesWidth;
    fieldInfo.Width = fieldInfoInit.Width;
    _fields.Add(fieldInfo);
  }
}

static UString GetPropName(PROPID propID, BSTR name)
{
  for (int i = 0; i < sizeof(kPropIdToName) / sizeof(kPropIdToName[0]); i++)
  {
    const CPropIdToName &propIdToName = kPropIdToName[i];
    if (propIdToName.PropID == propID)
      return propIdToName.Name;
  }
  if (name)
    return name;
  return L"?";
}

HRESULT CFieldPrinter::Init(IInArchive *archive)
{
  Clear();
  UInt32 numProps;
  RINOK(archive->GetNumberOfProperties(&numProps));
  for (UInt32 i = 0; i < numProps; i++)
  {
    CMyComBSTR name;
    PROPID propID;
    VARTYPE vt;
    RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt));
    CFieldInfo fieldInfo;
    fieldInfo.PropID = propID;
    fieldInfo.Name = GetPropName(propID, name);
    _fields.Add(fieldInfo);
  }
  return S_OK;
}

void CFieldPrinter::PrintTitle()
{
  for (int i = 0; i < _fields.Size(); i++)
  {
    const CFieldInfo &fieldInfo = _fields[i];
    PrintSpaces(fieldInfo.PrefixSpacesWidth);
    PrintString(fieldInfo.TitleAdjustment, 
      ((fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width), fieldInfo.Name);
  }
}

void CFieldPrinter::PrintTitleLines()
{
  for (int i = 0; i < _fields.Size(); i++)
  {
    const CFieldInfo &fieldInfo = _fields[i];
    PrintSpaces(fieldInfo.PrefixSpacesWidth);
    for (int i = 0; i < fieldInfo.Width; i++)
      g_StdOut << '-';
  }
}


BOOL IsFileTimeZero(CONST FILETIME *lpFileTime)
{
  return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0);
}

static const char *kEmptyTimeString = "                   ";
void PrintTime(const NCOM::CPropVariant &propVariant)
{
  if (propVariant.vt != VT_FILETIME)
    throw "incorrect item";
  if (IsFileTimeZero(&propVariant.filetime))
    g_StdOut << kEmptyTimeString;
  else
  {
    FILETIME localFileTime;
    if (!FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime))
      throw "FileTimeToLocalFileTime error";
    char s[32];
    if (ConvertFileTimeToString(localFileTime, s, true, true))
      g_StdOut << s;
    else
      g_StdOut << kEmptyTimeString;
  }
}

HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive, 
    const UString &defaultItemName, 
    const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
    UInt32 index,
    bool techMode)
{
  /*
  if (techMode)
  {
    g_StdOut << "Index = ";
    g_StdOut << (UInt64)index;
    g_StdOut << endl;
  }
  */

⌨️ 快捷键说明

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