diff --git a/sakura_core/CDataProfile.h b/sakura_core/CDataProfile.h index 85c7e1be04..e8ca795761 100644 --- a/sakura_core/CDataProfile.h +++ b/sakura_core/CDataProfile.h @@ -26,6 +26,8 @@ #define SAKURA_CDATAPROFILE_401640FD_5B27_454A_B0DE_098E1C4FAEAD_H_ #pragma once +#include "basis/SakuraBasis.h" +#include "debug/Debug2.h" #include "util/StaticType.h" #include "CProfile.h" @@ -166,8 +168,8 @@ class CDataProfile : public CProfile{ */ template //T=={bool, int, WORD, wchar_t, char, StringBufferW, StaticString} bool IOProfileData( - const std::wstring& strSectionName, //!< [in] セクション名 - const std::wstring& strEntryKey, //!< [in] エントリ名 + std::wstring_view sectionName, //!< [in] セクション名 + std::wstring_view entryKey, //!< [in] エントリ名 T& tEntryValue //!< [in,out] エントリ値 ) noexcept { @@ -177,7 +179,7 @@ class CDataProfile : public CProfile{ bool ret = false; if( IsReadingMode() ){ //文字列読み込み - if( GetProfileDataImp( strSectionName, strEntryKey, buf ) ){ + if( GetProfileData(sectionName, entryKey, buf) ){ //Tに変換 profile_to_value(buf, &tEntryValue); ret = true; @@ -185,8 +187,9 @@ class CDataProfile : public CProfile{ }else{ //文字列に変換 value_to_profile(tEntryValue, &buf); + ret = true; //TODO: 変換成否の反映 //文字列書き込み - ret = SetProfileDataImp( strSectionName, strEntryKey, buf ); + SetProfileData(sectionName, entryKey, buf); } return ret; } @@ -208,19 +211,18 @@ class CDataProfile : public CProfile{ */ template <> inline bool CDataProfile::IOProfileData( - const std::wstring& strSectionName, //!< [in] セクション名 - const std::wstring& strEntryKey, //!< [in] エントリ名 + std::wstring_view sectionName, //!< [in] セクション名 + std::wstring_view entryKey, //!< [in] エントリ名 std::wstring& strEntryValue //!< [in,out] エントリ値 ) noexcept { - bool ret = false; if( IsReadingMode() ){ //文字列読み込み - ret = GetProfileDataImp( strSectionName, strEntryKey, strEntryValue ); + return GetProfileData(sectionName, entryKey, strEntryValue); }else{ //文字列書き込み - ret = SetProfileDataImp( strSectionName, strEntryKey, strEntryValue ); + SetProfileData(sectionName, entryKey, strEntryValue); + return true; } - return ret; } #endif /* SAKURA_CDATAPROFILE_401640FD_5B27_454A_B0DE_098E1C4FAEAD_H_ */ diff --git a/sakura_core/CProfile.cpp b/sakura_core/CProfile.cpp index 09d3bcc2ee..9e4fe37e1a 100644 --- a/sakura_core/CProfile.cpp +++ b/sakura_core/CProfile.cpp @@ -35,6 +35,13 @@ */ #include "StdAfx.h" #include "CProfile.h" + +#include +#include +#include +#include +#include + #include "io/CTextStream.h" #include "charset/CUtf8.h" // Resource読み込みに使用 #include "CEol.h" @@ -313,10 +320,6 @@ bool CProfile::_WriteFile( return true; } -// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- // -// Imp // -// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- // - /*! エントリ値をProfileから読み込む @retval true 成功 @@ -324,19 +327,19 @@ bool CProfile::_WriteFile( @date 2003-10-22 D.S.Koba 作成 */ -bool CProfile::GetProfileDataImp( - const wstring& strSectionName, //!< [in] セクション名 - const wstring& strEntryKey, //!< [in] エントリ名 - wstring& strEntryValue //!< [out] エントリ値 -) +bool CProfile::GetProfileData( + std::wstring_view sectionName, //!< [in] セクション名 + std::wstring_view entryKey, //!< [in] エントリ名 + std::wstring& strEntryValue //!< [out] エントリ値 +) const { - for(auto iter = m_ProfileData.begin(); iter != m_ProfileData.end(); iter++ ) { - if( iter->strSectionName == strSectionName ) { - auto mapiter = iter->mapEntries.find( strEntryKey ); - if( iter->mapEntries.end() != mapiter ) { - strEntryValue = mapiter->second; - return true; - } + // セクション名が一致するセクションを探す + if (const auto iter = std::find_if(m_ProfileData.begin(), m_ProfileData.end(), [§ionName](const auto& section) {return section.strSectionName == sectionName; }); iter != m_ProfileData.end()) { + // キーが一致するエントリを探す + if (const auto mapiter = iter->mapEntries.find(entryKey.data()); iter->mapEntries.end() != mapiter) { + // エントリの値をコピーする + strEntryValue = mapiter->second; + return true; } } return false; @@ -344,42 +347,24 @@ bool CProfile::GetProfileDataImp( /*! エントリをProfileへ書き込む - @retval true 成功 - @retval false 失敗(処理を入れていないのでfalseは返らない) - @date 2003-10-21 D.S.Koba 作成 */ -bool CProfile::SetProfileDataImp( - const wstring& strSectionName, //!< [in] セクション名 - const wstring& strEntryKey, //!< [in] エントリ名 - const wstring& strEntryValue //!< [in] エントリ値 +void CProfile::SetProfileData( + std::wstring_view sectionName, //!< [in] セクション名 + std::wstring_view entryKey, //!< [in] エントリ名 + std::wstring_view entryValue //!< [in] エントリ値 ) { - auto iter = m_ProfileData.begin(); - for(; iter != m_ProfileData.end(); iter++ ) { - if( iter->strSectionName == strSectionName ) { - //既存のセクションの場合 - auto mapiter = iter->mapEntries.find( strEntryKey ); - if( iter->mapEntries.end() != mapiter ) { - //既存のエントリの場合は値を上書き - mapiter->second = strEntryValue; - break; - } - else { - //既存のエントリが見つからない場合は追加 - iter->mapEntries.insert( PAIR_STR_STR( strEntryKey, strEntryValue ) ); - break; - } - } + // セクション名が一致するセクションがない場合、空のセクションを追加する + if (const auto iter = std::find_if(m_ProfileData.begin(), m_ProfileData.end(), [§ionName](const auto& section) {return section.strSectionName == sectionName; }); iter == m_ProfileData.end()) { + m_ProfileData.emplace_back(Section{ sectionName.data() }); } - //既存のセクションではない場合,セクション及びエントリを追加 - if( iter == m_ProfileData.end() ) { - Section Buffer; - Buffer.strSectionName = strSectionName; - Buffer.mapEntries.insert( PAIR_STR_STR( strEntryKey, strEntryValue ) ); - m_ProfileData.push_back( Buffer ); + // セクション名が一致するセクションを探す + if (auto iter = std::find_if(m_ProfileData.begin(), m_ProfileData.end(), [§ionName](const auto& section) {return section.strSectionName == sectionName; }); iter != m_ProfileData.end()) { + // エントリに指定された値を書き込む + auto& sectionEntries = iter->mapEntries; + sectionEntries[entryKey.data()] = entryValue; } - return true; } void CProfile::DUMP( void ) diff --git a/sakura_core/CProfile.h b/sakura_core/CProfile.h index d1e2d412a9..79c8f145ce 100644 --- a/sakura_core/CProfile.h +++ b/sakura_core/CProfile.h @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -61,8 +62,8 @@ class CProfile }; public: - CProfile() {} - ~CProfile() {} + CProfile() = default; + virtual ~CProfile() = default; void Init( void ); bool IsReadingMode( void ) { return m_bRead; } void SetReadingMode( void ) { m_bRead = true; } @@ -70,6 +71,8 @@ class CProfile bool ReadProfile( const WCHAR* ); bool ReadProfileRes( const WCHAR*, const WCHAR*, std::vector* = NULL ); // 200/5/19 Uchi bool WriteProfile( const WCHAR*, const WCHAR* pszComment); + bool GetProfileData(std::wstring_view sectionName, std::wstring_view entryKey, std::wstring& strEntryValue) const; + void SetProfileData(std::wstring_view sectionName, std::wstring_view entryKey, std::wstring_view entryValue); void DUMP( void ); @@ -77,10 +80,6 @@ class CProfile void ReadOneline( const wstring& line ); bool _WriteFile( const wstring& strFilename, const std::vector< wstring >& vecLine); - bool GetProfileDataImp( const wstring& strSectionName, const wstring& strEntryKey, wstring& strEntryValue); - - bool SetProfileDataImp( const wstring& strSectionName, const wstring& strEntryKey, const wstring& strEntryValue ); - protected: // メンバ変数 wstring m_strProfileName; //!< 最後に読み書きしたファイル名 diff --git a/tests/unittests/test-cdlgprofilemgr.cpp b/tests/unittests/test-cdlgprofilemgr.cpp index 30e657d628..209cecb64f 100644 --- a/tests/unittests/test-cdlgprofilemgr.cpp +++ b/tests/unittests/test-cdlgprofilemgr.cpp @@ -48,6 +48,7 @@ #include "env/DLLSHAREDATA.h" #include "_main/CCommandLine.h" #include "_main/CControlProcess.h" +#include "CDataProfile.h" #include "util/file.h" /*! @@ -132,12 +133,16 @@ TEST_F( CDlgProfileMgrTest, TrySelectProfile_003 ) TEST_F( CDlgProfileMgrTest, TrySelectProfile_004 ) { // プロファイル設定を作る - SProfileSettings settings; - settings.m_szDllLanguage[0] = L'\0'; - settings.m_nDefaultIndex = 3; - settings.m_vProfList = { L"保存用", L"鑑賞用", L"使用用" }; - settings.m_bDefaultSelect = true; - CDlgProfileMgr::WriteProfSettings( settings ); + CDataProfile cProfile; + cProfile.SetWritingMode(); + cProfile.SetProfileData(L"Profile", L"szDllLanguage", L""); + cProfile.SetProfileData(L"Profile", L"nDefaultIndex", L"3"); + cProfile.SetProfileData(L"Profile", L"nCount", L"3"); + cProfile.SetProfileData(L"Profile", L"P[1]", L"保存用"); + cProfile.SetProfileData(L"Profile", L"P[2]", L"鑑賞用"); + cProfile.SetProfileData(L"Profile", L"P[3]", L"使用用"); + cProfile.SetProfileData(L"Profile", L"bDefaultSelect", L"1"); + cProfile.WriteProfile(profileMgrIniPath.c_str(), L"Sakura Profile ini"); // プロファイルマネージャー設定にデフォルト定義があればプロファイルは確定する CCommandLineWrapper cCommandLine; @@ -150,12 +155,16 @@ TEST_F( CDlgProfileMgrTest, TrySelectProfile_004 ) TEST_F( CDlgProfileMgrTest, TrySelectProfile_005 ) { // プロファイル設定を作る - SProfileSettings settings; - settings.m_szDllLanguage[0] = L'\0'; - settings.m_nDefaultIndex = 4; - settings.m_vProfList = { L"保存用", L"鑑賞用", L"使用用" }; - settings.m_bDefaultSelect = true; - CDlgProfileMgr::WriteProfSettings( settings ); + CDataProfile cProfile; + cProfile.SetWritingMode(); + cProfile.SetProfileData(L"Profile", L"szDllLanguage", L""); + cProfile.SetProfileData(L"Profile", L"nDefaultIndex", L"4"); + cProfile.SetProfileData(L"Profile", L"nCount", L"3"); + cProfile.SetProfileData(L"Profile", L"P[1]", L"保存用"); + cProfile.SetProfileData(L"Profile", L"P[2]", L"鑑賞用"); + cProfile.SetProfileData(L"Profile", L"P[3]", L"使用用"); + cProfile.SetProfileData(L"Profile", L"bDefaultSelect", L"1"); + cProfile.WriteProfile(profileMgrIniPath.c_str(), L"Sakura Profile ini"); // プロファイルマネージャー設定のデフォルト定義がおかしればプロファイルは確定しない CCommandLineWrapper cCommandLine; @@ -168,11 +177,12 @@ TEST_F( CDlgProfileMgrTest, TrySelectProfile_005 ) TEST_F( CDlgProfileMgrTest, TrySelectProfile_006 ) { // 空のプロファイル設定を作る - SProfileSettings settings; - settings.m_szDllLanguage[0] = L'\0'; - settings.m_nDefaultIndex = -1; - settings.m_bDefaultSelect = false; - CDlgProfileMgr::WriteProfSettings( settings ); + CDataProfile cProfile; + cProfile.SetWritingMode(); + cProfile.SetProfileData(L"Profile", L"szDllLanguage", L""); + cProfile.SetProfileData(L"Profile", L"nDefaultIndex", L"-1"); + cProfile.SetProfileData(L"Profile", L"bDefaultSelect", L"0"); + cProfile.WriteProfile(profileMgrIniPath.c_str(), L"Sakura Profile ini"); // プロファイルマネージャー設定が空定義ならプロファイルは確定しない CCommandLineWrapper cCommandLine; diff --git a/tests/unittests/test-cprofile.cpp b/tests/unittests/test-cprofile.cpp index 20b1dfdb6b..499656077a 100644 --- a/tests/unittests/test-cprofile.cpp +++ b/tests/unittests/test-cprofile.cpp @@ -38,6 +38,7 @@ #include #include "util/file.h" +#include "CDataProfile.h" /*! * @brief WriteProfileは指定されたパスに含まれるサブディレクトリを作成する @@ -69,3 +70,110 @@ TEST( CProfile, WriteProfileMakesSubDirectories ) p[0] = L'\0'; std::filesystem::remove( szIniName ); } + +/*! + * @brief GetProfileDataのテスト + */ +TEST(CProfile, GetProfileData_NoSection) +{ + CProfile cProfile; + cProfile.SetReadingMode(); + + // 初期状態は空なのでセクションが見つからない + std::wstring value; + ASSERT_FALSE(cProfile.GetProfileData(L"存在しないセクション名", L"szTest", value)); +} + +/*! + * @brief GetProfileDataのテスト + */ +TEST(CProfile, GetProfileData_NewSection) +{ + CProfile cProfile; + cProfile.SetReadingMode(); + + std::wstring value; + ASSERT_FALSE(cProfile.GetProfileData(L"Test", L"szTest", value)); + + // セクションを追加 + cProfile.SetProfileData(L"Test", L"szTest", L"value"); + + // 追加されたセクションを取得 + ASSERT_TRUE(cProfile.GetProfileData(L"Test", L"szTest", value)); + ASSERT_STREQ(L"value", value.data()); +} + +/*! + * @brief GetProfileDataのテスト + */ +TEST(CProfile, GetProfileData_NoEntry) +{ + CProfile cProfile; + cProfile.SetReadingMode(); + + std::wstring value; + ASSERT_FALSE(cProfile.GetProfileData(L"Test", L"szTest", value)); + + cProfile.SetProfileData(L"Test", L"szTest", L"value"); + + ASSERT_TRUE(cProfile.GetProfileData(L"Test", L"szTest", value)); + ASSERT_STREQ(L"value", value.data()); + + // 該当するキーがないのでエントリを取得できない + ASSERT_FALSE(cProfile.GetProfileData(L"Test", L"nTest", value)); +} + +/*! + * @brief GetProfileDataのテスト + */ +TEST(CProfile, GetProfileData_NewEntry) +{ + CProfile cProfile; + cProfile.SetReadingMode(); + + std::wstring value; + ASSERT_FALSE(cProfile.GetProfileData(L"Test", L"szTest", value)); + + cProfile.SetProfileData(L"Test", L"szTest", L"value"); + + ASSERT_TRUE(cProfile.GetProfileData(L"Test", L"szTest", value)); + ASSERT_STREQ(L"value", value.data()); + + ASSERT_FALSE(cProfile.GetProfileData(L"Test", L"nTest", value)); + + cProfile.SetProfileData(L"Test", L"nTest", L"109"); + + ASSERT_TRUE(cProfile.GetProfileData(L"Test", L"nTest", value)); + ASSERT_STREQ(L"109", value.data()); +} + +/*! + * @brief IOProfileDataのテスト + */ +TEST(CDataProfile, IOProfileData) +{ + CDataProfile cProfile; + cProfile.SetReadingMode(); + + std::wstring value; + ASSERT_FALSE(cProfile.IOProfileData(L"Test", L"szTest", value)); + + cProfile.SetProfileData(L"Test", L"szTest", L"value"); + + ASSERT_TRUE(cProfile.IOProfileData(L"Test", L"szTest", value)); + ASSERT_STREQ(L"value", value.data()); + + ASSERT_FALSE(cProfile.IOProfileData(L"Test", L"nTest", value)); + + cProfile.SetProfileData(L"Test", L"nTest", L"109"); + + ASSERT_TRUE(cProfile.IOProfileData(L"Test", L"nTest", value)); + ASSERT_STREQ(L"109", value.data()); + + int nValue = 0; + ASSERT_TRUE(cProfile.IOProfileData(L"Test", L"nTest", nValue)); + ASSERT_EQ(109, nValue); + + ASSERT_TRUE(cProfile.IOProfileData(L"Test", L"szTest", nValue)); + ASSERT_EQ(0, nValue); +} diff --git a/tests/unittests/test-file.cpp b/tests/unittests/test-file.cpp index 2710850db6..81f37b42c5 100644 --- a/tests/unittests/test-file.cpp +++ b/tests/unittests/test-file.cpp @@ -43,6 +43,7 @@ #include "env/DLLSHAREDATA.h" #include "_main/CCommandLine.h" #include "_main/CControlProcess.h" +#include "CDataProfile.h" #include "util/file.h" /*! @@ -387,18 +388,10 @@ TEST(file, GetInidirOrExedir) auto iniBasePath = GetIniFileName().parent_path().append(filename); // EXE基準のファイルを作る - { - std::wofstream ofs(exeBasePath); - ofs << L"TEST(file, GetInidirOrExedir)" << std::endl; - } + CProfile().WriteProfile(exeBasePath.c_str(), L"file, GetInidirOrExedirのテスト"); // INI基準のファイルを作る - { - EnsureDirectoryExist(GetIniFileName().replace_filename(L"").c_str()); - - std::wofstream ofs(iniBasePath); - ofs << L"TEST(file, GetInidirOrExedir)" << std::endl; - } + CProfile().WriteProfile(iniBasePath.c_str(), L"file, GetInidirOrExedirのテスト"); // 両方あるときはINI基準のパスが変える GetInidirOrExedir(buf.data(), filename, true); @@ -440,21 +433,13 @@ TEST(file, GetIniFileNameForIO) ASSERT_STREQ(iniPath.c_str(), GetIniFileNameForIO(false).c_str()); // 書き込みモードでないがiniファイルが実在するとき - { - std::wofstream ofs(iniPath); - ofs << L"test" << std::endl; - ofs.close(); - - // 実在チェック - ASSERT_TRUE(fexist(iniPath.c_str())); - - // テスト実施 - ASSERT_STREQ(iniPath.c_str(), GetIniFileNameForIO(false).c_str()); + CProfile().WriteProfile(iniPath.c_str(), L"file, GetIniFileNameForIOのテスト"); + ASSERT_TRUE(fexist(iniPath.c_str())); - // INIファイルを削除する - std::filesystem::remove(iniPath); + // テスト実施 + ASSERT_STREQ(iniPath.c_str(), GetIniFileNameForIO(false).c_str()); - // 削除チェック - ASSERT_FALSE(fexist(iniPath.c_str())); - } + // INIファイルを削除する + std::filesystem::remove(iniPath); + ASSERT_FALSE(fexist(iniPath.c_str())); }