From eeb30e8f452de6c71f60a407a03f7f7117efb4f3 Mon Sep 17 00:00:00 2001 From: Brodie Thiesfield Date: Thu, 17 Mar 2011 04:52:28 +0000 Subject: prepare for 4.14 release * change Load() to LoadData() to avoid confusion * add support for GetDoubleValue/SetDoubleValue --- SimpleIni.h | 140 ++++++++++++++++++++++++++++++++++++++++++++++++----- package.cmd | 5 +- snippets.cpp | 2 +- test1-expected.ini | 8 +-- test1.cpp | 8 +-- testsi.cpp | 16 +++--- 6 files changed, 149 insertions(+), 30 deletions(-) diff --git a/SimpleIni.h b/SimpleIni.h index 3b6fb64..a6793d6 100644 --- a/SimpleIni.h +++ b/SimpleIni.h @@ -77,7 +77,7 @@ #1 On Windows you are better to use CSimpleIniA with SI_CONVERT_WIN32.
#2 Only affects Windows. On Windows this uses MBCS functions and so may fold case incorrectly leading to uncertain results. - -# Call Load() or LoadFile() to load and parse the INI configuration file + -# Call LoadData() or LoadFile() to load and parse the INI configuration file -# Access and modify the data of the file using the following functions
GetAllSections Return all section names @@ -162,6 +162,9 @@ - Usage of the header on Windows can be disabled by defining SI_NO_MBCS. This is defined automatically on Windows CE platforms. + @section contrib CONTRIBUTIONS + + - 2010/05/03: Tobias Gehrig: added GetDoubleValue() @section licence MIT LICENCE @@ -456,6 +459,9 @@ public: /** Deallocate all memory stored by this object */ void Reset(); + /** Has any data been loaded */ + bool IsEmpty() const { return m_data.empty(); } + /*-----------------------------------------------------------------------*/ /** @{ @name Settings */ @@ -578,7 +584,7 @@ public: @return SI_Error See error definitions */ - SI_Error Load( + SI_Error LoadData( std::istream & a_istream ); #endif // SI_SUPPORT_IOSTREAMS @@ -589,8 +595,8 @@ public: @return SI_Error See error definitions */ - SI_Error Load(const std::string & a_strData) { - return Load(a_strData.c_str(), a_strData.size()); + SI_Error LoadData(const std::string & a_strData) { + return LoadData(a_strData.c_str(), a_strData.size()); } /** Load INI file data direct from memory @@ -600,7 +606,7 @@ public: @return SI_Error See error definitions */ - SI_Error Load( + SI_Error LoadData( const char * a_pData, size_t a_uDataLen ); @@ -879,6 +885,26 @@ public: bool * a_pHasMultiple = NULL ) const; + /** Retrieve a numeric value for a specific key. If multiple keys are enabled + (see SetMultiKey) then only the first value associated with that key + will be returned, see GetAllValues for getting all values with multikey. + + @param a_pSection Section to search + @param a_pKey Key to search for + @param a_nDefault Value to return if the key is not found + @param a_pHasMultiple Optionally receive notification of if there are + multiple entries for this key. + + @return a_nDefault Key was not found in the section + @return other Value of the key + */ + double GetDoubleValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + double a_nDefault = 0, + bool * a_pHasMultiple = NULL + ) const; + /** Retrieve a boolean value for a specific key. If multiple keys are enabled (see SetMultiKey) then only the first value associated with that key will be returned, see GetAllValues for getting all values with multikey. @@ -976,6 +1002,34 @@ public: bool a_bForceReplace = false ); + /** Add or update a double value. This will always insert + when multiple keys are enabled. + + @param a_pSection Section to add or update + @param a_pKey Key to add or update. + @param a_nValue Value to set. + @param a_pComment Comment to be associated with the key. See the + notes on SetValue() for comments. + @param a_bForceReplace Should all existing values in a multi-key INI + file be replaced with this entry. This option has + no effect if not using multi-key files. The + difference between Delete/SetDoubleValue and + SetDoubleValue with a_bForceReplace = true, is that + the load order and comment will be preserved this + way. + + @return SI_Error See error definitions + @return SI_UPDATED Value was updated + @return SI_INSERTED Value was inserted + */ + SI_Error SetDoubleValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + double a_nValue, + const SI_CHAR * a_pComment = NULL, + bool a_bForceReplace = false + ); + /** Add or update a boolean value. This will always insert when multiple keys are enabled. @@ -1312,14 +1366,14 @@ CSimpleIniTempl::LoadFile( } // convert the raw data to unicode - SI_Error rc = Load(pData, uRead); + SI_Error rc = LoadData(pData, uRead); delete[] pData; return rc; } template SI_Error -CSimpleIniTempl::Load( +CSimpleIniTempl::LoadData( const char * a_pData, size_t a_uDataLen ) @@ -1396,7 +1450,7 @@ CSimpleIniTempl::Load( #ifdef SI_SUPPORT_IOSTREAMS template SI_Error -CSimpleIniTempl::Load( +CSimpleIniTempl::LoadData( std::istream & a_istream ) { @@ -1407,7 +1461,7 @@ CSimpleIniTempl::Load( strData.append(szBuf); } while (a_istream.good()); - return Load(strData); + return LoadData(strData); } #endif // SI_SUPPORT_IOSTREAMS @@ -1878,7 +1932,7 @@ CSimpleIniTempl::AddEntry( if (a_pComment) { oKey.pComment = a_pComment; } - typename TKeyVal::value_type oEntry(oKey, (const SI_CHAR *) NULL); + typename TKeyVal::value_type oEntry(oKey, static_cast(NULL)); iKey = keyval.insert(oEntry); bInserted = true; } @@ -1994,6 +2048,68 @@ CSimpleIniTempl::SetLongValue( return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace, true); } +template +double +CSimpleIniTempl::GetDoubleValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + double a_nDefault, + bool * a_pHasMultiple + ) const +{ + // return the default if we don't have a value + const SI_CHAR * pszValue = GetValue(a_pSection, a_pKey, NULL, a_pHasMultiple); + if (!pszValue || !*pszValue) return a_nDefault; + + // convert to UTF-8/MBCS which for a numeric value will be the same as ASCII + char szValue[64] = { 0 }; + SI_CONVERTER c(m_bStoreIsUtf8); + if (!c.ConvertToStore(pszValue, szValue, sizeof(szValue))) { + return a_nDefault; + } + + char * pszSuffix = NULL; + double nValue = strtod(szValue, &pszSuffix); + + // any invalid strings will return the default value + if (!pszSuffix || *pszSuffix) { + return a_nDefault; + } + + return nValue; +} + +template +SI_Error +CSimpleIniTempl::SetDoubleValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + double a_nValue, + const SI_CHAR * a_pComment, + bool a_bForceReplace + ) +{ + // use SetValue to create sections + if (!a_pSection || !a_pKey) return SI_FAIL; + + // convert to an ASCII string + char szInput[64]; +#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE + sprintf_s(szInput, "%f", a_nValue); +#else // !__STDC_WANT_SECURE_LIB__ + sprintf(szInput, "%f", a_nValue); +#endif // __STDC_WANT_SECURE_LIB__ + + // convert to output text + SI_CHAR szOutput[64]; + SI_CONVERTER c(m_bStoreIsUtf8); + c.ConvertFromStore(szInput, strlen(szInput) + 1, + szOutput, sizeof(szOutput) / sizeof(SI_CHAR)); + + // actually add it + return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace, true); +} + template bool CSimpleIniTempl::GetBoolValue( @@ -2349,11 +2465,11 @@ CSimpleIniTempl::Save( if (m_bAllowMultiLine && IsMultiLineData(iValue->pItem)) { // multi-line data needs to be processed specially to ensure // that we use the correct newline format for the current system - a_oOutput.Write("<<pItem)) { return SI_FAIL; } - a_oOutput.Write("SI-END-OF-MULTILINE-TEXT"); + a_oOutput.Write("END_OF_TEXT"); } else { a_oOutput.Write(convert.Data()); diff --git a/package.cmd b/package.cmd index 59aaa87..f46da2c 100644 --- a/package.cmd +++ b/package.cmd @@ -1,4 +1,4 @@ -set VERSION=4.13 +set VERSION=4.14 set SEVENZIP="C:\Program Files\7-Zip\7z.exe" @@ -14,6 +14,9 @@ DEL /Q "SimpleIni.ncb" ATTRIB -H "SimpleIni.suo" DEL /Q "SimpleIni.suo" DEL /Q "SimpleIni.opt" +DEL /Q testsi-out*.ini +DEL /Q test1-blah.ini +DEL /Q test1-output.ini START "Generate documentation" /WAIT "C:\Program Files (x86)\doxygen\bin\doxygen.exe" SimpleIni.doxy cd .. del simpleini-%VERSION%.zip diff --git a/snippets.cpp b/snippets.cpp index 28e475c..e2295fe 100644 --- a/snippets.cpp +++ b/snippets.cpp @@ -34,7 +34,7 @@ snippets( // load from a string std::string strData; - rc = ini.Load(strData.c_str(), strData.size()); + rc = ini.LoadData(strData.c_str(), strData.size()); if (rc < 0) return false; // GETTING SECTIONS AND KEYS diff --git a/test1-expected.ini b/test1-expected.ini index 4f19e99..ca2216c 100644 --- a/test1-expected.ini +++ b/test1-expected.ini @@ -55,7 +55,7 @@ test = d [multiline-3] ; This is obviously a multi-line entry -multiline-1 = <<