#include "FolderInfo.h" #include #include namespace PluginFolderInfo { FolderInfo::FolderInfo(const wchar_t* aPath, const wchar_t* aIniPath) { mySubFolderFlag = false; myHiddenFileFlag = false; mySystemFileFlag = false; myRegExpFilter = NULL; myRegExpFilterExtra = NULL; myLastUpdateTime = 0; Clear(); SetPath(aPath, aIniPath); } void FolderInfo::Clear() { mySize = 0; myFileCount = 0; myFolderCount = 0; } void FolderInfo::SetPath(const wchar_t* aPath, const wchar_t* aIniPath) { if (!aPath || 0 == aPath[0]) { myPath = L""; return; } myPath = aPath; if (wcsncmp(aPath, L".\\", 2) == 0 || wcsncmp(aPath, L"..\\", 3) == 0) { wchar_t* buf = new wchar_t[wcslen(aIniPath) + 1]; wcscpy(buf, aIniPath); wchar_t* iniFileName = wcsrchr(buf, '\\'); if (iniFileName) { iniFileName[1] = 0; myPath = buf; myPath += aPath; } delete[] buf; } if (myPath[myPath.size() - 1] != L'\\') { myPath += L"\\"; } } void FolderInfo::Update() { Clear(); if (myPath.length() == 0) { return; } CalculateSize(); myLastUpdateTime = GetTickCount(); } void FolderInfo::CalculateSize() { std::list folderQueue; folderQueue.push_back(myPath.c_str()); wchar_t searchPattern[MAX_PATH + 10]; wchar_t buffer[MAX_PATH]; char utf8Buf[MAX_PATH * 3]; WIN32_FIND_DATA findData; HANDLE findHandle; while (!folderQueue.empty()) { std::list::reference ref = folderQueue.front(); wsprintf(searchPattern, L"%s%s", ref.c_str(), L"\\*.*"); findHandle = ::FindFirstFile(searchPattern, &findData); if (INVALID_HANDLE_VALUE == findHandle) { folderQueue.pop_front(); continue; } do { // special case for "." and ".." if (_wcsicmp(findData.cFileName, L".") == 0 || _wcsicmp(findData.cFileName, L"..") == 0) { continue; } bool isFolder = (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) > 0; if (!myHiddenFileFlag && (findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) { continue; } else if (!mySystemFileFlag && (findData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)) { continue; } else if (!isFolder && myRegExpFilter) { int utf8BufLen = WideCharToMultiByte(CP_UTF8, 0, findData.cFileName, wcslen(findData.cFileName) + 1, utf8Buf, MAX_PATH * 3, NULL, NULL); if (0 != pcre_exec(myRegExpFilter, myRegExpFilterExtra, utf8Buf, utf8BufLen, 0, 0, NULL, 0)) { continue; } } if (isFolder) { myFolderCount++; if (mySubFolderFlag) { wsprintf(buffer, L"%s\\%s", ref.c_str(), findData.cFileName); folderQueue.push_back(buffer); } } else { myFileCount++; mySize += ((UINT64)findData.nFileSizeHigh << 32) + findData.nFileSizeLow; } } while (::FindNextFile(findHandle, &findData)); FindClose(findHandle); folderQueue.pop_front(); } } void FolderInfo::SetRegExpFilter(const wchar_t* aFilter) { if (myRegExpFilter) { pcre_free(myRegExpFilter); myRegExpFilter = NULL; myRegExpFilterExtra = NULL; } if (aFilter == NULL) { return; } int filterLen = wcslen(aFilter) + 1; int bufLen = WideCharToMultiByte(CP_UTF8, 0, aFilter, filterLen, NULL, 0, NULL, NULL); char* buf = new char[bufLen]; WideCharToMultiByte(CP_UTF8, 0, aFilter, filterLen, buf, bufLen, NULL, NULL); const char* error; int erroffset; myRegExpFilter = pcre_compile(buf, PCRE_UTF8, &error, &erroffset, NULL); if (myRegExpFilter) { myRegExpFilterExtra = pcre_study(myRegExpFilter, 0, &error); } } } // namespace PluginFolderInfo