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

📄 enumdiritems.cpp

📁 由7-zip提供的压缩、解压缩程序
💻 CPP
字号:
// EnumDirItems.cpp#include "StdAfx.h"#include "Common/StringConvert.h"#include "Common/Wildcard.h"#include "Common/MyCom.h"#include "EnumDirItems.h"using namespace NWindows;using namespace NFile;using namespace NName;void AddDirFileInfo(    const UString &prefix,        // prefix for logical path    const UString &fullPathName,  // path on disk: can be relative to some basePrefix    const NFind::CFileInfoW &fileInfo,     CObjectVector<CDirItem> &dirItems){  CDirItem item;  item.Attributes = fileInfo.Attributes;  item.Size = fileInfo.Size;  item.CreationTime = fileInfo.CreationTime;  item.LastAccessTime = fileInfo.LastAccessTime;  item.LastWriteTime = fileInfo.LastWriteTime;  item.Name = prefix + fileInfo.Name;  item.FullPath = fullPathName;  dirItems.Add(item);}#if 0 // FIXEDstatic void EnumerateDirectory(    const UString &baseFolderPrefix,  // base (disk) prefix for scanning      const UString &directory,         // additional disk prefix starting from baseFolderPrefix    const UString &prefix,            // logical prefix    CObjectVector<CDirItem> &dirItems,    UStringVector &errorPaths,    CRecordVector<DWORD> &errorCodes){  NFind::CEnumeratorW enumerator(baseFolderPrefix + directory + wchar_t(kAnyStringWildcard));  while (true)  {     NFind::CFileInfoW fileInfo;    bool found;    if (!enumerator.Next(fileInfo, found))    {      errorCodes.Add(::GetLastError());      errorPaths.Add(baseFolderPrefix + directory);      return;    }    if (!found)      break;    AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, dirItems);    if (fileInfo.IsDirectory())    {      EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter),           prefix + fileInfo.Name + wchar_t(kDirDelimiter), dirItems, errorPaths, errorCodes);    }  }}void EnumerateDirItems(    const UString &baseFolderPrefix,   // base (disk) prefix for scanning      const UStringVector &fileNames,    // names relative to baseFolderPrefix    const UString &archiveNamePrefix,     CObjectVector<CDirItem> &dirItems,    UStringVector &errorPaths,    CRecordVector<DWORD> &errorCodes){  for(int i = 0; i < fileNames.Size(); i++)  {    const UString &fileName = fileNames[i];    NFind::CFileInfoW fileInfo;    if (!NFind::FindFile(baseFolderPrefix + fileName, fileInfo))    {      errorCodes.Add(::GetLastError());      errorPaths.Add(baseFolderPrefix + fileName);      continue;    }    AddDirFileInfo(archiveNamePrefix, fileName, fileInfo, dirItems);    if (fileInfo.IsDirectory())    {      EnumerateDirectory(baseFolderPrefix, fileName + wchar_t(kDirDelimiter),           archiveNamePrefix + fileInfo.Name +  wchar_t(kDirDelimiter),           dirItems, errorPaths, errorCodes);    }  }}#endifstatic HRESULT EnumerateDirItems(    const NWildcard::CCensorNode &curNode,     const UString &diskPrefix,        // full disk path prefix     const UString &archivePrefix,     // prefix from root    const UStringVector &addArchivePrefix,  // prefix from curNode    CObjectVector<CDirItem> &dirItems,     bool enterToSubFolders,    IEnumDirItemCallback *callback,    UStringVector &errorPaths,    CRecordVector<DWORD> &errorCodes){  if (!enterToSubFolders)    if (curNode.NeedCheckSubDirs())      enterToSubFolders = true;  if (callback)    RINOK(callback->CheckBreak());  // try direct_names case at first  if (addArchivePrefix.IsEmpty() && !enterToSubFolders)  {    // check that all names are direct    int i;    for (i = 0; i < curNode.IncludeItems.Size(); i++)    {      const NWildcard::CItem &item = curNode.IncludeItems[i];      if (item.Recursive || item.PathParts.Size() != 1)        break;      const UString &name = item.PathParts.Front();      if (name.IsEmpty() || DoesNameContainWildCard(name))        break;    }    if (i == curNode.IncludeItems.Size())    {      // all names are direct (no wildcards)      // so we don't need file_system's dir enumerator      CRecordVector<bool> needEnterVector;      for (i = 0; i < curNode.IncludeItems.Size(); i++)      {        const NWildcard::CItem &item = curNode.IncludeItems[i];        const UString &name = item.PathParts.Front();        const UString fullPath = diskPrefix + name;        NFind::CFileInfoW fileInfo;        if (!NFind::FindFile(fullPath, fileInfo))        {          errorCodes.Add(::GetLastError());          errorPaths.Add(fullPath);          continue;        }        bool isDir = fileInfo.IsDirectory();        if (isDir && !item.ForDir || !isDir && !item.ForFile)        {          errorCodes.Add(E_FAIL);          errorPaths.Add(fullPath);          continue;        }        const UString realName = fileInfo.Name;        const UString realDiskPath = diskPrefix + realName;        {          UStringVector pathParts;          pathParts.Add(fileInfo.Name);          if (curNode.CheckPathToRoot(false, pathParts, !isDir))            continue;        }        AddDirFileInfo(archivePrefix, realDiskPath, fileInfo, dirItems);        if (!isDir)          continue;                UStringVector addArchivePrefixNew;        const NWildcard::CCensorNode *nextNode = 0;        int index = curNode.FindSubNode(name);        if (index >= 0)        {          for (int t = needEnterVector.Size(); t <= index; t++)            needEnterVector.Add(true);          needEnterVector[index] = false;          nextNode = &curNode.SubNodes[index];        }        else        {          nextNode = &curNode;          addArchivePrefixNew.Add(name); // don't change it to realName. It's for shortnames support        }        RINOK(EnumerateDirItems(*nextNode,               realDiskPath + wchar_t(kDirDelimiter),             archivePrefix + realName + wchar_t(kDirDelimiter),             addArchivePrefixNew, dirItems, true, callback, errorPaths, errorCodes));      }      for (i = 0; i < curNode.SubNodes.Size(); i++)      {        if (i < needEnterVector.Size())          if (!needEnterVector[i])            continue;        const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];        const UString fullPath = diskPrefix + nextNode.Name;        NFind::CFileInfoW fileInfo;        if (!NFind::FindFile(fullPath, fileInfo))        {          if (!nextNode.AreThereIncludeItems())            continue;          errorCodes.Add(::GetLastError());          errorPaths.Add(fullPath);          continue;        }        if (!fileInfo.IsDirectory())        {          errorCodes.Add(E_FAIL);          errorPaths.Add(fullPath);          continue;        }        RINOK(EnumerateDirItems(nextNode,             diskPrefix + fileInfo.Name + wchar_t(kDirDelimiter),             archivePrefix + fileInfo.Name + wchar_t(kDirDelimiter),             UStringVector(), dirItems, false, callback, errorPaths, errorCodes));      }      return S_OK;    }  }  NFind::CEnumeratorW enumerator(diskPrefix + wchar_t(kAnyStringWildcard));  while (true)  {    NFind::CFileInfoW fileInfo;    bool found;    if (!enumerator.Next(fileInfo, found))    {      errorCodes.Add(::GetLastError());      errorPaths.Add(diskPrefix);      break;    }    if (!found)      break;    if (callback)      RINOK(callback->CheckBreak());    const UString &name = fileInfo.Name;    bool enterToSubFolders2 = enterToSubFolders;    UStringVector addArchivePrefixNew = addArchivePrefix;    addArchivePrefixNew.Add(name);    {      UStringVector addArchivePrefixNewTemp(addArchivePrefixNew);      if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fileInfo.IsDirectory()))        continue;    }    if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fileInfo.IsDirectory()))    {      AddDirFileInfo(archivePrefix, diskPrefix + name, fileInfo, dirItems);      if (fileInfo.IsDirectory())        enterToSubFolders2 = true;    }    if (!fileInfo.IsDirectory())      continue;    const NWildcard::CCensorNode *nextNode = 0;    if (addArchivePrefix.IsEmpty())    {      int index = curNode.FindSubNode(name);      if (index >= 0)        nextNode = &curNode.SubNodes[index];    }    if (!enterToSubFolders2 && nextNode == 0)      continue;    addArchivePrefixNew = addArchivePrefix;    if (nextNode == 0)    {      nextNode = &curNode;      addArchivePrefixNew.Add(name);    }    RINOK(EnumerateDirItems(*nextNode,           diskPrefix + name + wchar_t(kDirDelimiter),         archivePrefix + name + wchar_t(kDirDelimiter),         addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes));  }  return S_OK;}HRESULT EnumerateItems(    const NWildcard::CCensor &censor,     CObjectVector<CDirItem> &dirItems,     IEnumDirItemCallback *callback,    UStringVector &errorPaths,    CRecordVector<DWORD> &errorCodes){  for (int i = 0; i < censor.Pairs.Size(); i++)  {    const NWildcard::CPair &pair = censor.Pairs[i];    RINOK(EnumerateDirItems(pair.Head, pair.Prefix, L"", UStringVector(), dirItems, false,         callback, errorPaths, errorCodes));  }  return S_OK;}

⌨️ 快捷键说明

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