From 33621fcfffe3f8305fda0310636f0ac7bf214450 Mon Sep 17 00:00:00 2001 From: berryzplus Date: Sun, 7 Mar 2021 15:40:11 +0900 Subject: [PATCH 1/4] =?UTF-8?q?CFilePath::GetExt=E3=81=AE=E5=87=A6?= =?UTF-8?q?=E7=90=86=E6=A7=8B=E9=80=A0=E3=81=AB=E3=82=B3=E3=83=A1=E3=83=B3?= =?UTF-8?q?=E3=83=88=E3=82=92=E4=BB=98=E3=81=91=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sakura_core/basis/CMyString.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sakura_core/basis/CMyString.h b/sakura_core/basis/CMyString.h index 0d9df9c678..37608c2064 100644 --- a/sakura_core/basis/CMyString.h +++ b/sakura_core/basis/CMyString.h @@ -62,17 +62,25 @@ class CFilePath : public StaticString{ //拡張子を取得する LPCWSTR GetExt( bool bWithoutDot = false ) const { + // 文字列の先頭アドレスを取得 const WCHAR* head = c_str(); + + // 文字列の末尾アドレスを取得 const WCHAR* p = wcschr(head,L'\0') - 1; + + // 文字列末尾から逆方向に [\.\\/] を検索 while(p>=head){ if(*p==L'.')break; if(*p==L'\\')break; if(*p==L'/')break; p--; } + + // pが文字列範囲内で、\. を指している場合 if(p>=head && *p==L'.'){ return bWithoutDot ? p+1 : p; //bWithoutDot==trueならドットなしを返す }else{ + // 文字列末尾のアドレスを返す return wcschr(head,L'\0'); } } From 8a765a845b8d01bdcf6e5690680bb17f0b56690d Mon Sep 17 00:00:00 2001 From: berryzplus Date: Sun, 7 Mar 2021 15:49:17 +0900 Subject: [PATCH 2/4] =?UTF-8?q?CFilePath::GetExt=E3=81=AE=E3=83=86?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/unittests/test-file.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/unittests/test-file.cpp b/tests/unittests/test-file.cpp index b4fc49e539..95c6c8205f 100644 --- a/tests/unittests/test-file.cpp +++ b/tests/unittests/test-file.cpp @@ -443,3 +443,32 @@ TEST(file, GetIniFileNameForIO) std::filesystem::remove(iniPath); ASSERT_FALSE(fexist(iniPath.c_str())); } + +/*! + GetExtのテスト + */ +TEST(CFilePath, GetExt) +{ + CFilePath path; + + // 最も単純なパターン + path = L"test.txt"; + ASSERT_STREQ(L".txt", path.GetExt()); + ASSERT_STREQ(L"txt", path.GetExt(true)); + + // ファイルに拡張子がないパターン + path = L"lib\\.NET Core\\README"; + ASSERT_STREQ(L"", path.GetExt()); + ASSERT_STREQ(L"", path.GetExt(true)); + + // 拡張子がない場合に返却されるポインタ値の確認 + ASSERT_EQ(path.c_str() + path.Length(), path.GetExt()); + + // ファイルに拡張子がないパターン + path = L"lib/.NET Core/README"; + ASSERT_STREQ(L"", path.GetExt()); + ASSERT_STREQ(L"", path.GetExt(true)); + + // 拡張子がない場合に返却されるポインタ値の確認 + ASSERT_EQ(path.c_str() + path.Length(), path.GetExt()); +} From db1ec4d348c4f643b96244afe63703117ddb0b6c Mon Sep 17 00:00:00 2001 From: berryzplus Date: Sun, 7 Mar 2021 16:27:00 +0900 Subject: [PATCH 3/4] =?UTF-8?q?CFilePath::GetExt=E3=81=AE=E3=83=AA?= =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=AF=E3=82=BF=E3=83=AA=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sakura_core/basis/CMyString.h | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/sakura_core/basis/CMyString.h b/sakura_core/basis/CMyString.h index 37608c2064..33f72dee7e 100644 --- a/sakura_core/basis/CMyString.h +++ b/sakura_core/basis/CMyString.h @@ -62,27 +62,22 @@ class CFilePath : public StaticString{ //拡張子を取得する LPCWSTR GetExt( bool bWithoutDot = false ) const { - // 文字列の先頭アドレスを取得 - const WCHAR* head = c_str(); - // 文字列の末尾アドレスを取得 - const WCHAR* p = wcschr(head,L'\0') - 1; + const WCHAR* tail = c_str() + Length(); - // 文字列末尾から逆方向に [\.\\/] を検索 - while(p>=head){ - if(*p==L'.')break; - if(*p==L'\\')break; - if(*p==L'/')break; - p--; + // 文字列末尾から逆方向に L'.' を検索 + if (const auto *p = ::wcsrchr(c_str(), L'.')) { + // L'.'で始まる文字列がパス区切りを含まない場合のみ「拡張子あり」と看做す + if (const bool hasExt = !::wcspbrk(p, L"\\/"); hasExt && !bWithoutDot) { + return p; + } + else if (hasExt && p < tail) { + return p + 1; //bWithoutDot==trueならドットなしを返す + } } - // pが文字列範囲内で、\. を指している場合 - if(p>=head && *p==L'.'){ - return bWithoutDot ? p+1 : p; //bWithoutDot==trueならドットなしを返す - }else{ - // 文字列末尾のアドレスを返す - return wcschr(head,L'\0'); - } + // 文字列末尾のアドレスを返す + return tail; } }; From d80d26837b83a13e53bc55518f5268371b54a22d Mon Sep 17 00:00:00 2001 From: berryzplus Date: Sun, 7 Mar 2021 18:05:46 +0900 Subject: [PATCH 4/4] =?UTF-8?q?CFilePath=E3=81=AB=E9=96=A2=E3=81=99?= =?UTF-8?q?=E3=82=8BCodeSmell=E3=82=92=E5=AF=BE=E7=AD=96=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sakura_core/basis/CMyString.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sakura_core/basis/CMyString.h b/sakura_core/basis/CMyString.h index 33f72dee7e..3003eced21 100644 --- a/sakura_core/basis/CMyString.h +++ b/sakura_core/basis/CMyString.h @@ -45,11 +45,11 @@ class CFilePath : public StaticString{ private: typedef StaticString Super; public: - CFilePath() : Super() { } + CFilePath() = default; CFilePath(const WCHAR* rhs) : Super(rhs) { } - bool IsValidPath() const{ return At(0)!=L'\0'; } - std::wstring GetDirPath() const + [[nodiscard]] bool IsValidPath() const{ return At(0)!=L'\0'; } + [[nodiscard]] std::wstring GetDirPath() const { WCHAR szDirPath[_MAX_PATH]; WCHAR szDrive[_MAX_DRIVE]; @@ -59,8 +59,9 @@ class CFilePath : public StaticString{ wcscat( szDirPath, szDir ); return szDirPath; } + //拡張子を取得する - LPCWSTR GetExt( bool bWithoutDot = false ) const + [[nodiscard]] LPCWSTR GetExt( bool bWithoutDot = false ) const { // 文字列の末尾アドレスを取得 const WCHAR* tail = c_str() + Length();