From 122196ed1cb820b64add54224942f794c6435888 Mon Sep 17 00:00:00 2001 From: kobake Date: Sat, 27 Jun 2020 09:49:04 +0900 Subject: [PATCH] Change indent sytle: tab -> 4space --- locate32/src/main.cpp | 628 +++++++++++++++++++------------------- locate32/src/stream.cpp | 116 +++---- locate32/src/stream.h | 38 +-- updatedb32/src/main.cpp | 302 +++++++++--------- updatedb32/src/stream.cpp | 96 +++--- updatedb32/src/stream.h | 46 +-- 6 files changed, 613 insertions(+), 613 deletions(-) diff --git a/locate32/src/main.cpp b/locate32/src/main.cpp index 78812a5..960a0be 100644 --- a/locate32/src/main.cpp +++ b/locate32/src/main.cpp @@ -14,21 +14,21 @@ int main_routine(const char* pattern); int ParseIndent(const wchar_t* szText) { - const wchar_t* p = szText; - while(*p==L'\t')p++; - return (int)(p-szText); + const wchar_t* p = szText; + while(*p==L'\t')p++; + return (int)(p-szText); } const wchar_t* wcsistr(const wchar_t* str1, const wchar_t* str2) { - int len1 = (int)wcslen(str1); - int len2 = (int)wcslen(str2); - int cnt = len1 - len2 + 1; - const wchar_t* p = str1; - for(int i=0;i& args); std::string w2a(std::wstring wstr) { - int n = ::WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL); - std::vector buf(n + 1); - n = ::WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), &buf[0], n, NULL, NULL); - buf[n] = 0; - return &buf[0]; + int n = ::WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL); + std::vector buf(n + 1); + n = ::WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), &buf[0], n, NULL, NULL); + buf[n] = 0; + return &buf[0]; } std::wstring a2w(std::string str) { - int n = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0); - std::vector buf(n + 1); - n = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &buf[0], n); - buf[n] = 0; - return &buf[0]; + int n = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0); + std::vector buf(n + 1); + n = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &buf[0], n); + buf[n] = 0; + return &buf[0]; } int wmain(int argc, wchar_t* argv[]) { - setlocale(LC_ALL, "jpn"); - - std::vector args; - for(int i = 1; i < argc; i++){ - args.push_back(w2a(argv[i])); - } - /* - char* argv[] = {"locate32.exe", "こんにちは", "hoge", "fuga", "piyo", "xxx", "yyy", "--size=10G", "ppp", "vvv"}; - //wchar_t* argv_w[] = {L"locate32.exe", L"こんにちは"}; - int argc = _countof(argv); - */ - return main2(args); + setlocale(LC_ALL, "jpn"); + + std::vector args; + for(int i = 1; i < argc; i++){ + args.push_back(w2a(argv[i])); + } + /* + char* argv[] = {"locate32.exe", "こんにちは", "hoge", "fuga", "piyo", "xxx", "yyy", "--size=10G", "ppp", "vvv"}; + //wchar_t* argv_w[] = {L"locate32.exe", L"こんにちは"}; + int argc = _countof(argv); + */ + return main2(args); } inline bool IS_DIGIT(char c){ return c >= '0' && c <= '9'; } class SizeOption{ public: - // [+-]N[bcwkMG] - /* - -size n[bcwkMG]- this will return a list of files having size “n” (of course as discussed at the beginning of part II the list can consist of files bigger than n (+n), smaller (-n) or equal n. The letter after the number define size unit. Use: - b – for 512 bytes blocks (b for blocks); - c – for bytes (c for – I have no idea, probably b was already in use); - w – for two bytes words (w for words); - k – for Kilobytes (1024 bytes); - M – for Megabytes (1048576 bytes); - G – for Gigabytes (1073741824 bytes). - */ - SizeOption(const char* str = "") - { - m_kind = 999; - m_size = 0; - // パース - const char* p = str; - if(!p)return; - if(!*p)return; - char c; - // 先頭文字 - c = *p; - if(c == '+')m_kind = 1, p++; // bigger - else if(c == '-')m_kind = -1, p++; // smaller - //else if(c == '=')m_kind = 0, p++; // equal - else if(IS_DIGIT(c))m_kind = 0; // equal - else{ - std::string s = (std::string)"Invalid size specification: " + str; - throw std::exception(s.c_str()); - } - // 後続数値 - if(!IS_DIGIT(*p)){ - std::string s = (std::string)"Invalid size specification: " + str; - throw std::exception(s.c_str()); - } - m_size = 0; - while(IS_DIGIT(c = *p++)){ - m_size *= 10; - long long n = c - '0'; - m_size += n; - } - // 末尾単位 - long long unit = 512; // default: 512bytes block - switch(c){ - case '\0': unit = 512; break; // 512bytes block (default) - case ' ': unit = 512; break; // 512bytes block (default) - case 'b': unit = 512; break; // 512bytes block - case 'c': unit = 1; break; // byte - case 'w': unit = 2; break; // 2byte word - case 'k': unit = 1024; break; // KBytes (1024 bytes) - case 'M': unit = 1024 * 1024; break; // MBytes (1024 * 1024 = 1048576 bytes) - case 'G': unit = 1024 * 1024 * 1024; break; // GBytes (1024 * 1024 * 1024 = 1073741824 bytes) - default: - { - std::string s = (std::string)"Invalid size specification: " + str; - throw std::exception(s.c_str()); - } - } - // 格納 - m_size *= unit; - } - bool Match(const wchar_t* attributes) - { - if(m_kind == 999){ - // 条件チェック無し - return true; - } - - // アイテムのサイズ - long long attrsize = attr2size(attributes); - - // 等 - if(m_kind == 0){ - return attrsize == m_size; - } - // より上 - else if(m_kind == 1){ - return attrsize >= m_size; - } - // より下 - else if(m_kind == -1){ - return attrsize <= m_size; - } - - // 例外 (条件チェック無し) - return true; - } - - // FolderSize:xxx または Size:xxx を検出 - static long long attr2size(const wchar_t* attrs) - { - const wchar_t* p; - p = wcsstr(attrs, L"FolderSize:"); - if(p){ - p += (_countof(L"FolderSize:") - 1); - return ::_wtoi64(p); - } - p = wcsstr(attrs, L"Size:"); - if(p){ - p += (_countof(L"Size:") - 1); - return ::_wtoi64(p); - } - return 0; - } + // [+-]N[bcwkMG] + /* + -size n[bcwkMG]- this will return a list of files having size “n” (of course as discussed at the beginning of part II the list can consist of files bigger than n (+n), smaller (-n) or equal n. The letter after the number define size unit. Use: + b – for 512 bytes blocks (b for blocks); + c – for bytes (c for – I have no idea, probably b was already in use); + w – for two bytes words (w for words); + k – for Kilobytes (1024 bytes); + M – for Megabytes (1048576 bytes); + G – for Gigabytes (1073741824 bytes). + */ + SizeOption(const char* str = "") + { + m_kind = 999; + m_size = 0; + // パース + const char* p = str; + if(!p)return; + if(!*p)return; + char c; + // 先頭文字 + c = *p; + if(c == '+')m_kind = 1, p++; // bigger + else if(c == '-')m_kind = -1, p++; // smaller + //else if(c == '=')m_kind = 0, p++; // equal + else if(IS_DIGIT(c))m_kind = 0; // equal + else{ + std::string s = (std::string)"Invalid size specification: " + str; + throw std::exception(s.c_str()); + } + // 後続数値 + if(!IS_DIGIT(*p)){ + std::string s = (std::string)"Invalid size specification: " + str; + throw std::exception(s.c_str()); + } + m_size = 0; + while(IS_DIGIT(c = *p++)){ + m_size *= 10; + long long n = c - '0'; + m_size += n; + } + // 末尾単位 + long long unit = 512; // default: 512bytes block + switch(c){ + case '\0': unit = 512; break; // 512bytes block (default) + case ' ': unit = 512; break; // 512bytes block (default) + case 'b': unit = 512; break; // 512bytes block + case 'c': unit = 1; break; // byte + case 'w': unit = 2; break; // 2byte word + case 'k': unit = 1024; break; // KBytes (1024 bytes) + case 'M': unit = 1024 * 1024; break; // MBytes (1024 * 1024 = 1048576 bytes) + case 'G': unit = 1024 * 1024 * 1024; break; // GBytes (1024 * 1024 * 1024 = 1073741824 bytes) + default: + { + std::string s = (std::string)"Invalid size specification: " + str; + throw std::exception(s.c_str()); + } + } + // 格納 + m_size *= unit; + } + bool Match(const wchar_t* attributes) + { + if(m_kind == 999){ + // 条件チェック無し + return true; + } + + // アイテムのサイズ + long long attrsize = attr2size(attributes); + + // 等 + if(m_kind == 0){ + return attrsize == m_size; + } + // より上 + else if(m_kind == 1){ + return attrsize >= m_size; + } + // より下 + else if(m_kind == -1){ + return attrsize <= m_size; + } + + // 例外 (条件チェック無し) + return true; + } + + // FolderSize:xxx または Size:xxx を検出 + static long long attr2size(const wchar_t* attrs) + { + const wchar_t* p; + p = wcsstr(attrs, L"FolderSize:"); + if(p){ + p += (_countof(L"FolderSize:") - 1); + return ::_wtoi64(p); + } + p = wcsstr(attrs, L"Size:"); + if(p){ + p += (_countof(L"Size:") - 1); + return ::_wtoi64(p); + } + return 0; + } private: - int m_kind; // 比較方法 999:無し 0:equal 1:bigger -1:smaller - long long m_size; // 比較基準サイズ + int m_kind; // 比較方法 999:無し 0:equal 1:bigger -1:smaller + long long m_size; // 比較基準サイズ }; SizeOption g_sizeOption; int main2(const std::vector& args) { - try{ - // オプション一覧 - std::string sizeOption = ""; - - // オプション - po::options_description gen("Options"); - gen.add_options() - ("help,h", "Display this help message") - ("size,s", po::value(&sizeOption)->value_name("[+-]N[bcwkMG]"), "File size for filtering (Specifying it as one of 'find' command options)") - ; - - // 非表示オプション - po::options_description hidden("Hidden options"); - hidden.add_options() - ("input-file", po::value< vector >(), "input file"); // 任意個受け取りたいものは、vectorで。 - - // 非オプション引数 - po::positional_options_description pos; - pos.add("input-file", -1); // -1とすることで、全てのpositionalオプションが、"input-file"であると解釈される(vectorに、ざくざく入っていく) - - // 全て - po::options_description cmdline_options; - cmdline_options.add(gen).add(hidden); - - po::variables_map values; - //po::store(po::parse_command_line(argc, argv, desc), values); - po::store(po::command_line_parser(args).options(cmdline_options).positional(pos).run(), values); - po::notify(values); - - // ヘルプが押されたら - if (values.count("help")) { - std::cout << "Usage: locate32 [options] \n"; - std::cout << "Search for entries in a mlocate32 database.\n"; - std::cout << "\n"; - std::cout << gen << "\n"; - std::cout << "Sample usage:\n"; - std::cout << " locate32 hoge.exe # Match named \"*hoge.exe*\".\n"; - std::cout << " locate32 .dat -s +10M # Match named \"*.dat*\" and size is bigger than 10MB.\n"; - std::cout << " locate32 .dat -s +10G # Match named \"*.dat*\" and size is bigger than 10GB.\n"; - return 1; - } - - // サイズオプション取得 - /* - if(values.count("size")){ - sizeOption = values["size"].as(); - std::cout << "size = " << sizeOption << "\n"; - } - */ - //std::cout << "sizeOption = " << sizeOption << "\n"; - - // 通常引数 - std::string pattern; - if (values.count("input-file")) - { - const std::vector& v = values["input-file"].as< std::vector >(); - /* - std::cout << "---------------------\n"; - for(int i = 0; i < (int)v.size(); i++){ - std::cout << i << ":" << v[i] << "\n"; - } - std::cout << "---------------------\n"; - */ - //std::cout << "Input files are: " << << "\n"; - pattern = v[0]; - } - else{ - std::cout << "locate32: no pattern to search for specified\n"; - return 1; - } - - // 処理 - g_sizeOption = SizeOption(sizeOption.c_str()); - return main_routine(pattern.c_str()); - } - catch(const std::exception& ex){ - std::cout << "Error: " << ex.what() << "\n"; - return 1; - } - - // サイズ指定があったら - - /* - auto interpreter = Interpreter(); - - if (vm.count("xboard")) { - interpreter.is_running_over_xboard = true; - } - interpreter.prompt(); - */ + try{ + // オプション一覧 + std::string sizeOption = ""; + + // オプション + po::options_description gen("Options"); + gen.add_options() + ("help,h", "Display this help message") + ("size,s", po::value(&sizeOption)->value_name("[+-]N[bcwkMG]"), "File size for filtering (Specifying it as one of 'find' command options)") + ; + + // 非表示オプション + po::options_description hidden("Hidden options"); + hidden.add_options() + ("input-file", po::value< vector >(), "input file"); // 任意個受け取りたいものは、vectorで。 + + // 非オプション引数 + po::positional_options_description pos; + pos.add("input-file", -1); // -1とすることで、全てのpositionalオプションが、"input-file"であると解釈される(vectorに、ざくざく入っていく) + + // 全て + po::options_description cmdline_options; + cmdline_options.add(gen).add(hidden); + + po::variables_map values; + //po::store(po::parse_command_line(argc, argv, desc), values); + po::store(po::command_line_parser(args).options(cmdline_options).positional(pos).run(), values); + po::notify(values); + + // ヘルプが押されたら + if (values.count("help")) { + std::cout << "Usage: locate32 [options] \n"; + std::cout << "Search for entries in a mlocate32 database.\n"; + std::cout << "\n"; + std::cout << gen << "\n"; + std::cout << "Sample usage:\n"; + std::cout << " locate32 hoge.exe # Match named \"*hoge.exe*\".\n"; + std::cout << " locate32 .dat -s +10M # Match named \"*.dat*\" and size is bigger than 10MB.\n"; + std::cout << " locate32 .dat -s +10G # Match named \"*.dat*\" and size is bigger than 10GB.\n"; + return 1; + } + + // サイズオプション取得 + /* + if(values.count("size")){ + sizeOption = values["size"].as(); + std::cout << "size = " << sizeOption << "\n"; + } + */ + //std::cout << "sizeOption = " << sizeOption << "\n"; + + // 通常引数 + std::string pattern; + if (values.count("input-file")) + { + const std::vector& v = values["input-file"].as< std::vector >(); + /* + std::cout << "---------------------\n"; + for(int i = 0; i < (int)v.size(); i++){ + std::cout << i << ":" << v[i] << "\n"; + } + std::cout << "---------------------\n"; + */ + //std::cout << "Input files are: " << << "\n"; + pattern = v[0]; + } + else{ + std::cout << "locate32: no pattern to search for specified\n"; + return 1; + } + + // 処理 + g_sizeOption = SizeOption(sizeOption.c_str()); + return main_routine(pattern.c_str()); + } + catch(const std::exception& ex){ + std::cout << "Error: " << ex.what() << "\n"; + return 1; + } + + // サイズ指定があったら + + /* + auto interpreter = Interpreter(); + + if (vm.count("xboard")) { + interpreter.is_running_over_xboard = true; + } + interpreter.prompt(); + */ } /* int wmain(int argc, wchar_t* argv[]) { - try{ - return wmain_routine(argc, argv); - } - catch(const exception& e){ - wprintf(L"Error: %hs\n", e.what()); - } + try{ + return wmain_routine(argc, argv); + } + catch(const exception& e){ + wprintf(L"Error: %hs\n", e.what()); + } }*/ int main_routine(const char* pattern) { - std::wstring wstrPattern = a2w(pattern); - - const wchar_t* szKeyword = wstrPattern.c_str(); - - //現在のディレクトリを取得 - //例「D:\abc\def」「\\landisk\abc\def」「D:」 - wchar_t szCurDir[XP_MAX_PATH]; - ::GetCurrentDirectory(_countof(szCurDir), szCurDir); - { - //末尾の「\」は削る - wchar_t* p = wcsrchr(szCurDir, L'\\'); - if(p && *(p+1)==L'\0')*p = L'\0'; - } - - //現在のドライブを取得 - //例「C:」「D:」 - wstring strDrive; - { - const wchar_t* p = szCurDir; - while(*p==L'\\')p++; - const wchar_t* q = wcschr(p, L'\\'); - if(!q)q = wcschr(p, L'\0'); - strDrive.assign(p, q); - } - - //データベースファイル名を生成 - //例「D:\updatedb」 - wstring strDatabaseFile = strDrive + L"\\updatedb"; -// wprintf(L"Output to [%ls] ...\n", strDatabaseFile.c_str()); - - //読み込み開始 - CReader in(strDatabaseFile.c_str()); - if(!in.IsValid())throw myexception("Can't read [%ls]", strDatabaseFile.c_str()); - - //巡回 - wchar_t szLine[XP_MAX_PATH]; - wstring aIndentNames[512]; - while(in.ReadLine(szLine, _countof(szLine))){ - //インデント取得・インデント除去 - int nIndent = ParseIndent(szLine); - wchar_t* pLine = szLine + nIndent; - if(nIndent>=_countof(aIndentNames)){ - throw myexception("Indent [%d] is too long; than %d.", nIndent, (int)_countof(aIndentNames)); - } - - //インデント位置へのアイテム文字列記録 - const wchar_t* tab = wcschr(pLine, '\t'); - if(tab){ - aIndentNames[nIndent].assign(pLine, tab - pLine); - } - else{ - aIndentNames[nIndent] = pLine; - } - const wchar_t* pCurrentName = aIndentNames[nIndent].c_str(); - - //キーワードマッチ - if(wcsistr(pCurrentName, szKeyword)){ - // サイズチェック - if(!g_sizeOption.Match(tab))continue; - - // フルパス出力 - for(int i=0;i=_countof(aIndentNames)){ + throw myexception("Indent [%d] is too long; than %d.", nIndent, (int)_countof(aIndentNames)); + } + + //インデント位置へのアイテム文字列記録 + const wchar_t* tab = wcschr(pLine, '\t'); + if(tab){ + aIndentNames[nIndent].assign(pLine, tab - pLine); + } + else{ + aIndentNames[nIndent] = pLine; + } + const wchar_t* pCurrentName = aIndentNames[nIndent].c_str(); + + //キーワードマッチ + if(wcsistr(pCurrentName, szKeyword)){ + // サイズチェック + if(!g_sizeOption.Match(tab))continue; + + // フルパス出力 + for(int i=0;i= m_pEnd){ //※+1は終端ヌル分 - throw myexception("file line is too long."); - return false; - } - ::wmemcpy(m_pCur, begin, len); - m_pCur[len] = 0; - m_pCur += len; //※終端ヌル分は進めない - return true; - } - int Length() const - { - return (int)(m_pCur - m_pBuf); - } + OutputBuffer(wchar_t* pBuf, int nBufLen) + : m_pBuf(pBuf), m_pEnd(pBuf+nBufLen) + { + m_pCur = m_pBuf; + } + bool Push(const wchar_t* begin, const wchar_t* end) + { + int len = (int)(end-begin); + if(m_pCur+len+1 >= m_pEnd){ //※+1は終端ヌル分 + throw myexception("file line is too long."); + return false; + } + ::wmemcpy(m_pCur, begin, len); + m_pCur[len] = 0; + m_pCur += len; //※終端ヌル分は進めない + return true; + } + int Length() const + { + return (int)(m_pCur - m_pBuf); + } private: - wchar_t* m_pBuf; - wchar_t* m_pEnd; - wchar_t* m_pCur; + wchar_t* m_pBuf; + wchar_t* m_pEnd; + wchar_t* m_pCur; }; -wchar_t m_buf[1024]; -const wchar_t* p_buf_begin = m_buf; -const wchar_t* p_buf_end = m_buf; +wchar_t m_buf[1024]; +const wchar_t* p_buf_begin = m_buf; +const wchar_t* p_buf_end = m_buf; //1行読み込み。改行コードを含む。 bool CReader::ReadLine(wchar_t* pBuf, int nBufLen) { - OutputBuffer result(pBuf, nBufLen); + OutputBuffer result(pBuf, nBufLen); - while(1){ - //p_buf_beginが既に終端に達している場合、さらに読み込み - if(p_buf_begin >= p_buf_end){ - p_buf_begin = m_buf; - size_t nRead = ::fread(m_buf, sizeof(wchar_t), _countof(m_buf), m_fp); - p_buf_end = m_buf + nRead; - if(nRead==0)break; //もう読み込めないのでこれにて終了 - } + while(1){ + //p_buf_beginが既に終端に達している場合、さらに読み込み + if(p_buf_begin >= p_buf_end){ + p_buf_begin = m_buf; + size_t nRead = ::fread(m_buf, sizeof(wchar_t), _countof(m_buf), m_fp); + p_buf_end = m_buf + nRead; + if(nRead==0)break; //もう読み込めないのでこれにて終了 + } - //改行コードを探す - const wchar_t* q = wcschr(p_buf_begin, L'\n'); + //改行コードを探す + const wchar_t* q = wcschr(p_buf_begin, L'\n'); - //正常格納 - if(q){ - result.Push(p_buf_begin, q); - p_buf_begin = q + 1; - break; - } + //正常格納 + if(q){ + result.Push(p_buf_begin, q); + p_buf_begin = q + 1; + break; + } - //残りを全部格納 - result.Push(p_buf_begin, p_buf_end); - p_buf_begin = p_buf_end; - } - return result.Length() > 0; + //残りを全部格納 + result.Push(p_buf_begin, p_buf_end); + p_buf_begin = p_buf_end; + } + return result.Length() > 0; } diff --git a/locate32/src/stream.h b/locate32/src/stream.h index 08afd3d..470f6cb 100644 --- a/locate32/src/stream.h +++ b/locate32/src/stream.h @@ -3,23 +3,23 @@ #include //FILE #ifndef _countof - #define _countof(A) (sizeof(A) / sizeof(A[0])) + #define _countof(A) (sizeof(A) / sizeof(A[0])) #endif #if _MSC_VER < 1400 - #define vsprintf_s _vsnprintf - #define wcscat_s(A,B,C) wcsncat(A,C,B) - #define wcscpy_s(A,B,C) wcsncpy(A,C,B) + #define vsprintf_s _vsnprintf + #define wcscat_s(A,B,C) wcsncat(A,C,B) + #define wcscpy_s(A,B,C) wcsncpy(A,C,B) #endif class CReader{ public: - CReader(const wchar_t* szPath); - ~CReader(); - void Close(); - bool IsValid() const; - bool ReadLine(wchar_t* pBuf, int nBufLen); + CReader(const wchar_t* szPath); + ~CReader(); + void Close(); + bool IsValid() const; + bool ReadLine(wchar_t* pBuf, int nBufLen); private: - FILE* m_fp; + FILE* m_fp; }; @@ -29,14 +29,14 @@ class CReader{ class myexception : public std::exception{ public: - myexception(const char* str, ...) - { - va_list v; - va_start(v, str); - vsprintf_s(m_str, _countof(m_str), str, v); - va_end(v); - } - const char* what() const throw(){ return m_str; } + myexception(const char* str, ...) + { + va_list v; + va_start(v, str); + vsprintf_s(m_str, _countof(m_str), str, v); + va_end(v); + } + const char* what() const throw(){ return m_str; } private: - char m_str[256]; + char m_str[256]; }; diff --git a/updatedb32/src/main.cpp b/updatedb32/src/main.cpp index b25c021..f2e6dc1 100644 --- a/updatedb32/src/main.cpp +++ b/updatedb32/src/main.cpp @@ -14,9 +14,9 @@ void enum_and_print_start(CFileOutputStream& out, wchar_t* szDir); long long enum_and_print(CFileOutputStream& out, wchar_t* szDir, int nIndent); #ifdef _DEBUG - #define DBFILENAME L"updatedb_debug" + #define DBFILENAME L"updatedb_debug" #else - #define DBFILENAME L"updatedb" + #define DBFILENAME L"updatedb" #endif @@ -25,173 +25,173 @@ long long enum_and_print(CFileOutputStream& out, wchar_t* szDir, int nIndent); bool operator < (const WIN32_FIND_DATA& lhs, const WIN32_FIND_DATA& rhs) { - bool lhsDir = ((lhs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0); - bool rhsDir = ((rhs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0); - if(lhsDir != rhsDir){ - return lhsDir?true:false; - } - return _wcsicmp(lhs.cFileName, rhs.cFileName) < 0; + bool lhsDir = ((lhs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0); + bool rhsDir = ((rhs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0); + if(lhsDir != rhsDir){ + return lhsDir?true:false; + } + return _wcsicmp(lhs.cFileName, rhs.cFileName) < 0; } int wmain(int argc, wchar_t* argv[]) { - try{ - return main_routine(); - } - catch(const exception& e){ - printf("Error: %hs\n", e.what()); - } + try{ + return main_routine(); + } + catch(const exception& e){ + printf("Error: %hs\n", e.what()); + } } std::map g_sizes; int main_routine() { - setlocale(LC_ALL, "jpn"); - - //現在のディレクトリを取得 - //例「D:\abc\def」「\\landisk\abc\def」「D:」 - wchar_t szCurDir[XP_MAX_PATH]; - ::GetCurrentDirectory(_countof(szCurDir), szCurDir); - { - //末尾の「\」は削る - wchar_t* p = wcsrchr(szCurDir, L'\\'); - if(p && *(p+1)==L'\0')*p = L'\0'; - } - - //現在のドライブを取得 - //例「C:」「D:」 - wstring strDrive; - { - const wchar_t* p = szCurDir; - while(*p==L'\\')p++; - const wchar_t* q = wcschr(p, L'\\'); - if(!q)q = wcschr(p, L'\0'); - strDrive.assign(p, q); - } - - //データベースファイル名を生成 - //例「D:\updatedb」 - wstring strDatabaseFile = strDrive + L"\\" + DBFILENAME; - wprintf(L"Output to [%ls] ...\n", strDatabaseFile.c_str()); - - //書き込み開始 - CFileOutputStream out(strDatabaseFile.c_str()); - if(!out.IsValid())throw myexception("Can't write to [%ls].", strDatabaseFile.c_str()); -// FILE* fp = NULL; -// errno_t e = _wfopen_s(&fp, strDatabaseFile.c_str(), L"wb"); -// if(e!=0 || !fp)throw myexception("Can't write to [%ls].", strDatabaseFile.c_str()); - - //書き込み - g_sizes.clear(); - wchar_t szRootDir[XP_MAX_PATH]; - wcscpy_s(szRootDir, _countof(szRootDir), strDrive.c_str()); - enum_and_print_start(out, szRootDir); - - // 2stage - for(std::map::const_iterator itr = g_sizes.begin(); itr != g_sizes.end(); itr++){ - long long pos = itr->first; - long long size = itr->second; - out.Seek(pos); - out.WriteF(L"%020lld", size); - } - g_sizes.clear(); - - //書き込み終了 - out.Close(); - - //現在のドライブを取得 -// const wchar_t* p = wcschr(szCurDir, L'\\'); -// if(!p)p = wcschr(szCurDir, L'\0'); - return 0; + setlocale(LC_ALL, "jpn"); + + //現在のディレクトリを取得 + //例「D:\abc\def」「\\landisk\abc\def」「D:」 + wchar_t szCurDir[XP_MAX_PATH]; + ::GetCurrentDirectory(_countof(szCurDir), szCurDir); + { + //末尾の「\」は削る + wchar_t* p = wcsrchr(szCurDir, L'\\'); + if(p && *(p+1)==L'\0')*p = L'\0'; + } + + //現在のドライブを取得 + //例「C:」「D:」 + wstring strDrive; + { + const wchar_t* p = szCurDir; + while(*p==L'\\')p++; + const wchar_t* q = wcschr(p, L'\\'); + if(!q)q = wcschr(p, L'\0'); + strDrive.assign(p, q); + } + + //データベースファイル名を生成 + //例「D:\updatedb」 + wstring strDatabaseFile = strDrive + L"\\" + DBFILENAME; + wprintf(L"Output to [%ls] ...\n", strDatabaseFile.c_str()); + + //書き込み開始 + CFileOutputStream out(strDatabaseFile.c_str()); + if(!out.IsValid())throw myexception("Can't write to [%ls].", strDatabaseFile.c_str()); +// FILE* fp = NULL; +// errno_t e = _wfopen_s(&fp, strDatabaseFile.c_str(), L"wb"); +// if(e!=0 || !fp)throw myexception("Can't write to [%ls].", strDatabaseFile.c_str()); + + //書き込み + g_sizes.clear(); + wchar_t szRootDir[XP_MAX_PATH]; + wcscpy_s(szRootDir, _countof(szRootDir), strDrive.c_str()); + enum_and_print_start(out, szRootDir); + + // 2stage + for(std::map::const_iterator itr = g_sizes.begin(); itr != g_sizes.end(); itr++){ + long long pos = itr->first; + long long size = itr->second; + out.Seek(pos); + out.WriteF(L"%020lld", size); + } + g_sizes.clear(); + + //書き込み終了 + out.Close(); + + //現在のドライブを取得 +// const wchar_t* p = wcschr(szCurDir, L'\\'); +// if(!p)p = wcschr(szCurDir, L'\0'); + return 0; } void enum_and_print_start(CFileOutputStream& out, wchar_t* szDir) { - out.Write(szDir); - out.Write(L"\n"); - enum_and_print(out, szDir, 1); + out.Write(szDir); + out.Write(L"\n"); + enum_and_print(out, szDir, 1); } // アイテムのサイズを返す long long enum_and_print(CFileOutputStream& out, wchar_t* szDir, int nIndent) { - //CPUをあんまり食いつぶさないように。 - ::Sleep(1); - - //ワイルドカード式ファイルパスを構築 - wchar_t* szPath = szDir; - wcscat_s(szPath, XP_MAX_PATH, L"\\*"); - - //ファイルタイトル部分を覚えておく - wchar_t* pTitle = wcschr(szPath, L'\0') - 1; - int nTitleMax = XP_MAX_PATH - (int)(pTitle - szPath); - - //ファイル一覧収集 - WIN32_FIND_DATA fd; - HANDLE hFind = ::FindFirstFile(szPath, &fd); - std::list files; - if(hFind!=INVALID_HANDLE_VALUE){ - do{ - //「.」と「..」はスキップ - if(wcscmp(fd.cFileName, L".")==0)continue; - if(wcscmp(fd.cFileName, L"..")==0)continue; - - //リスト構築 - files.push_back(fd); - } - while(::FindNextFile(hFind, &fd)); - } - ::FindClose(hFind); - - //ファイル一覧ソート - files.sort(); - - //ファイル一覧処理 - long long totalsize = 0; - std::list::const_iterator p = files.begin(), q = files.end(); - for(; p != q; p++){ - //インデント出力 - for(int i=0;icFileName; - const WIN32_FIND_DATA* test2 = &(*p); - - out.Write(p->cFileName); - - // タブ区切りで属性値を出力 - out.Write(L"\t"); - long long size = p->nFileSizeLow | (((long long)p->nFileSizeHigh) << 32); - out.WriteF(L"Size:%lld", size); - //out.Seek(); - - //ディレクトリを再帰巡回 - if(p->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){ - if(p->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT){ - // シンボリックリンクまたはジャンクションなので配下は無視 - out.Write(L",Type:ReparsePoint\n"); - } - else{ - // フォルダ情報出力スペース予約 - out.WriteF(L",Type:Folder,FolderSize:xxxxxxxxxxxxxxxxxxxx", size); - long long foldersizepos = out.Tell() - 20 * 2; - out.Write(L"\n"); - // 配下情報 - wcscpy_s(pTitle, nTitleMax, p->cFileName); - size += enum_and_print(out, szPath, nIndent+1); - size += 10; - // 保存すべきサイズをひとまず保持(2stage目でこの値は吐き出す) - g_sizes[foldersizepos] = size; - } - } - else{ - out.Write(L",Type:File\n"); - } - - // サイズ加算 - totalsize += size; - } - return totalsize; + //CPUをあんまり食いつぶさないように。 + ::Sleep(1); + + //ワイルドカード式ファイルパスを構築 + wchar_t* szPath = szDir; + wcscat_s(szPath, XP_MAX_PATH, L"\\*"); + + //ファイルタイトル部分を覚えておく + wchar_t* pTitle = wcschr(szPath, L'\0') - 1; + int nTitleMax = XP_MAX_PATH - (int)(pTitle - szPath); + + //ファイル一覧収集 + WIN32_FIND_DATA fd; + HANDLE hFind = ::FindFirstFile(szPath, &fd); + std::list files; + if(hFind!=INVALID_HANDLE_VALUE){ + do{ + //「.」と「..」はスキップ + if(wcscmp(fd.cFileName, L".")==0)continue; + if(wcscmp(fd.cFileName, L"..")==0)continue; + + //リスト構築 + files.push_back(fd); + } + while(::FindNextFile(hFind, &fd)); + } + ::FindClose(hFind); + + //ファイル一覧ソート + files.sort(); + + //ファイル一覧処理 + long long totalsize = 0; + std::list::const_iterator p = files.begin(), q = files.end(); + for(; p != q; p++){ + //インデント出力 + for(int i=0;icFileName; + const WIN32_FIND_DATA* test2 = &(*p); + + out.Write(p->cFileName); + + // タブ区切りで属性値を出力 + out.Write(L"\t"); + long long size = p->nFileSizeLow | (((long long)p->nFileSizeHigh) << 32); + out.WriteF(L"Size:%lld", size); + //out.Seek(); + + //ディレクトリを再帰巡回 + if(p->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){ + if(p->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT){ + // シンボリックリンクまたはジャンクションなので配下は無視 + out.Write(L",Type:ReparsePoint\n"); + } + else{ + // フォルダ情報出力スペース予約 + out.WriteF(L",Type:Folder,FolderSize:xxxxxxxxxxxxxxxxxxxx", size); + long long foldersizepos = out.Tell() - 20 * 2; + out.Write(L"\n"); + // 配下情報 + wcscpy_s(pTitle, nTitleMax, p->cFileName); + size += enum_and_print(out, szPath, nIndent+1); + size += 10; + // 保存すべきサイズをひとまず保持(2stage目でこの値は吐き出す) + g_sizes[foldersizepos] = size; + } + } + else{ + out.Write(L",Type:File\n"); + } + + // サイズ加算 + totalsize += size; + } + return totalsize; } diff --git a/updatedb32/src/stream.cpp b/updatedb32/src/stream.cpp index 13bc0fc..c1dac7d 100644 --- a/updatedb32/src/stream.cpp +++ b/updatedb32/src/stream.cpp @@ -2,81 +2,81 @@ CFileOutputStream::CFileOutputStream(const wchar_t* szPath) { - m_hFile = ::CreateFile( - szPath, - GENERIC_WRITE, - FILE_SHARE_READ, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL - ); - m_dwPos = 0; + m_hFile = ::CreateFile( + szPath, + GENERIC_WRITE, + FILE_SHARE_READ, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + m_dwPos = 0; } CFileOutputStream::~CFileOutputStream() { - Close(); + Close(); } void CFileOutputStream::Close() { - if(m_hFile != INVALID_HANDLE_VALUE){ - ::CloseHandle(m_hFile); - m_hFile = INVALID_HANDLE_VALUE; - } + if(m_hFile != INVALID_HANDLE_VALUE){ + ::CloseHandle(m_hFile); + m_hFile = INVALID_HANDLE_VALUE; + } } bool CFileOutputStream::IsValid() const { - return m_hFile != INVALID_HANDLE_VALUE; + return m_hFile != INVALID_HANDLE_VALUE; } //ファイル出力実装 void CFileOutputStream::WriteF(const wchar_t* szText, ...) { - wchar_t buf[1024 * 4]; - va_list v; - va_start(v, szText); - _vsnwprintf_s(buf, _countof(buf) - 1, szText, v); - va_end(v); - Write(buf); + wchar_t buf[1024 * 4]; + va_list v; + va_start(v, szText); + _vsnwprintf_s(buf, _countof(buf) - 1, szText, v); + va_end(v); + Write(buf); } void CFileOutputStream::Write(const wchar_t* szText) { - //wprintf(L"%ls", szText); - DWORD nLen = (DWORD)(wcslen(szText) * sizeof(wchar_t)); - DWORD dwWrote = 0; - BOOL bRet = ::WriteFile( - m_hFile, - szText, - nLen, - &dwWrote, - NULL - ); - m_dwPos += dwWrote; - if(!bRet || dwWrote!=nLen){ - throw myexception("Write process failed."); - } + //wprintf(L"%ls", szText); + DWORD nLen = (DWORD)(wcslen(szText) * sizeof(wchar_t)); + DWORD dwWrote = 0; + BOOL bRet = ::WriteFile( + m_hFile, + szText, + nLen, + &dwWrote, + NULL + ); + m_dwPos += dwWrote; + if(!bRet || dwWrote!=nLen){ + throw myexception("Write process failed."); + } -// size_t nResult= fwrite(szText, sizeof(wchar_t), nLen, fp); -// if(nLen!=nResult){ -// throw myexception("Write process failed."); -// } +// size_t nResult= fwrite(szText, sizeof(wchar_t), nLen, fp); +// if(nLen!=nResult){ +// throw myexception("Write process failed."); +// } } long long CFileOutputStream::Tell() { - return (long long)m_dwPos; - /* - DWORD dw = 0; - ::GetFileSize(m_hFile, &dw); - return (long long)dw; - */ + return (long long)m_dwPos; + /* + DWORD dw = 0; + ::GetFileSize(m_hFile, &dw); + return (long long)dw; + */ } void CFileOutputStream::Seek(long long pos) { - ::SetFilePointer(m_hFile, (LONG)pos, NULL, FILE_BEGIN); - m_dwPos = (DWORD)pos; + ::SetFilePointer(m_hFile, (LONG)pos, NULL, FILE_BEGIN); + m_dwPos = (DWORD)pos; } diff --git a/updatedb32/src/stream.h b/updatedb32/src/stream.h index 330297b..3848d48 100644 --- a/updatedb32/src/stream.h +++ b/updatedb32/src/stream.h @@ -3,27 +3,27 @@ #include //HANDLE #ifndef _countof - #define _countof(A) (sizeof(A) / sizeof(A[0])) + #define _countof(A) (sizeof(A) / sizeof(A[0])) #endif #if _MSC_VER < 1400 - #define vsprintf_s _vsnprintf - #define wcscat_s(A,B,C) wcsncat(A,C,B) - #define wcscpy_s(A,B,C) wcsncpy(A,C,B) + #define vsprintf_s _vsnprintf + #define wcscat_s(A,B,C) wcsncat(A,C,B) + #define wcscpy_s(A,B,C) wcsncpy(A,C,B) #endif class CFileOutputStream{ public: - CFileOutputStream(const wchar_t* szPath); - ~CFileOutputStream(); - bool IsValid() const; - void Write(const wchar_t* szText); - void WriteF(const wchar_t* szText, ...); - void Close(); - long long Tell(); - void Seek(long long pos); + CFileOutputStream(const wchar_t* szPath); + ~CFileOutputStream(); + bool IsValid() const; + void Write(const wchar_t* szText); + void WriteF(const wchar_t* szText, ...); + void Close(); + long long Tell(); + void Seek(long long pos); private: - HANDLE m_hFile; - DWORD m_dwPos; + HANDLE m_hFile; + DWORD m_dwPos; }; @@ -32,14 +32,14 @@ class CFileOutputStream{ class myexception : public std::exception{ public: - myexception(const char* str, ...) - { - va_list v; - va_start(v, str); - vsprintf_s(m_str, _countof(m_str), str, v); - va_end(v); - } - const char* what() const throw(){ return m_str; } + myexception(const char* str, ...) + { + va_list v; + va_start(v, str); + vsprintf_s(m_str, _countof(m_str), str, v); + va_end(v); + } + const char* what() const throw(){ return m_str; } private: - char m_str[256]; + char m_str[256]; };