📄 enumdiritems.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 + -