diff options
author | Brodie Thiesfield <brofield@gmail.com> | 2011-03-17 07:52:28 +0300 |
---|---|---|
committer | Brodie Thiesfield <brofield@gmail.com> | 2011-03-17 07:52:28 +0300 |
commit | eeb30e8f452de6c71f60a407a03f7f7117efb4f3 (patch) | |
tree | 92f201e3e0d06281e36e4a4530424b5f485ddf3d | |
parent | 651fb0c58958644d1140e850b767f63ebb65264f (diff) |
prepare for 4.14 release
* change Load() to LoadData() to avoid confusion
* add support for GetDoubleValue/SetDoubleValue
-rw-r--r-- | SimpleIni.h | 140 | ||||
-rw-r--r-- | package.cmd | 5 | ||||
-rw-r--r-- | snippets.cpp | 2 | ||||
-rw-r--r-- | test1-expected.ini | 8 | ||||
-rw-r--r-- | test1.cpp | 8 | ||||
-rw-r--r-- | 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.<br> #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 <table> <tr><td>GetAllSections <td>Return all section names @@ -162,6 +162,9 @@ - Usage of the <mbstring.h> 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<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadFile( } // convert the raw data to unicode - SI_Error rc = Load(pData, uRead); + SI_Error rc = LoadData(pData, uRead); delete[] pData; return rc; } template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER> SI_Error -CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::Load( +CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadData( const char * a_pData, size_t a_uDataLen ) @@ -1396,7 +1450,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::Load( #ifdef SI_SUPPORT_IOSTREAMS template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER> SI_Error -CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::Load( +CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadData( std::istream & a_istream ) { @@ -1407,7 +1461,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::Load( strData.append(szBuf); } while (a_istream.good()); - return Load(strData); + return LoadData(strData); } #endif // SI_SUPPORT_IOSTREAMS @@ -1878,7 +1932,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::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<const SI_CHAR *>(NULL)); iKey = keyval.insert(oEntry); bInserted = true; } @@ -1995,6 +2049,68 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SetLongValue( } template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER> +double +CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::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<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER> +SI_Error +CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::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<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER> bool CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::GetBoolValue( const SI_CHAR * a_pSection, @@ -2349,11 +2465,11 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::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("<<<SI-END-OF-MULTILINE-TEXT" SI_NEWLINE_A); + a_oOutput.Write("<<<END_OF_TEXT" SI_NEWLINE_A); if (!OutputMultiLineText(a_oOutput, convert, iValue->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 = <<<SI-END-OF-MULTILINE-TEXT +multiline-1 = <<<END_OF_TEXT This is a multi-line comment. It will continue until we have the word MULTI @@ -63,7 +63,7 @@ on a line by itself. 日本語も。 -SI-END-OF-MULTILINE-TEXT +END_OF_TEXT ; This looks like multi-line, but because the newline following the last ; line is discarded, it will be converted into a single line entry. @@ -71,10 +71,10 @@ another-2 = This is not a multiline entry. ; If you wanted a multiline entry with a single line, you need to add ; an extra line to it. -another-3 = <<<SI-END-OF-MULTILINE-TEXT +another-3 = <<<END_OF_TEXT This is a multiline entry. -SI-END-OF-MULTILINE-TEXT +END_OF_TEXT [integer] @@ -128,10 +128,10 @@ bool TestStreams() // load the file try { - std::ifstream infile; - infile.open(rgszTestFile[0], std::ifstream::in | std::ifstream::binary); - if (ini.Load(infile) < 0) throw false; - infile.close(); + std::ifstream instream; + instream.open(rgszTestFile[0], std::ifstream::in | std::ifstream::binary); + if (ini.LoadData(instream) < 0) throw false; + instream.close(); } catch (...) { return oTest.Failure("Failed to load file"); @@ -154,10 +154,10 @@ TestStreams( // load the file CSimpleIni ini(a_bIsUtf8, a_bUseMultiKey, a_bUseMultiLine); _tprintf(_T("Loading file: %s\n"), a_pszFile); - std::ifstream infile; - infile.open(a_pszFile, std::ifstream::in | std::ifstream::binary); - SI_Error rc = ini.Load(infile); - infile.close(); + std::ifstream instream; + instream.open(a_pszFile, std::ifstream::in | std::ifstream::binary); + SI_Error rc = ini.LoadData(instream); + instream.close(); if (rc < 0) { printf("Failed to open file.\n"); return false; @@ -167,10 +167,10 @@ TestStreams( // save the file (simple) _tprintf(_T("\n-- Saving file to: testsi-out-streams.ini\n")); - std::ofstream outfile; - outfile.open("testsi-out-streams.ini", std::ofstream::out | std::ofstream::binary); - ini.Save(outfile); - outfile.close(); + std::ofstream outstream; + outstream.open("testsi-out-streams.ini", std::ofstream::out | std::ofstream::binary); + ini.Save(outstream); + outstream.close(); return true; } |