From 484f2cf2c810c3c57ff869470d8f1848316cca16 Mon Sep 17 00:00:00 2001 From: noryb009 Date: Mon, 21 Jul 2014 19:58:15 -0400 Subject: Add DeleteValue() DeleteValue() deletes a given key from a given section, if it has a given value. --- SimpleIni.h | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- snippets.cpp | 9 +++++++-- testsi.cpp | 6 ++++++ 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/SimpleIni.h b/SimpleIni.h index 503735f..2807a8f 100644 --- a/SimpleIni.h +++ b/SimpleIni.h @@ -1064,8 +1064,8 @@ public: data returned by GetSection is invalid and must not be used after anything has been deleted from that section using this method. Note when multiple keys is enabled, this will delete all keys with - that name; there is no way to selectively delete individual key/values - in this situation. + that name; to selectively delete individual key/values, use + DeleteValue. @param a_pSection Section to delete key from, or if a_pKey is NULL, the section to remove. @@ -1084,6 +1084,33 @@ public: bool a_bRemoveEmpty = false ); + /** Delete an entire section, or a key from a section. If value is + provided, only remove keys with the value. Note that the data + returned by GetSection is invalid and must not be used after + anything has been deleted from that section using this method. + Note when multiple keys is enabled, all keys with the value will + be deleted. + + @param a_pSection Section to delete key from, or if + a_pKey is NULL, the section to remove. + @param a_pKey Key to remove from the section. Set to + NULL to remove the entire section. + @param a_pValue Value of key to remove from the section. + Set to NULL to remove all keys. + @param a_bRemoveEmpty If the section is empty after this key has + been deleted, should the empty section be + removed? + + @return true Key/value or section was deleted. + @return false Key/value or section was not found. + */ + bool DeleteValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + const SI_CHAR * a_pValue, + bool a_bRemoveEmpty = false + ); + /*-----------------------------------------------------------------------*/ /** @} @{ @name Converter */ @@ -2527,6 +2554,18 @@ CSimpleIniTempl::Delete( const SI_CHAR * a_pKey, bool a_bRemoveEmpty ) +{ + return DeleteValue(a_pSection, a_pKey, NULL, a_bRemoveEmpty); +} + +template +bool +CSimpleIniTempl::DeleteValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + const SI_CHAR * a_pValue, + bool a_bRemoveEmpty + ) { if (!a_pSection) { return false; @@ -2544,18 +2583,30 @@ CSimpleIniTempl::Delete( return false; } + const static SI_STRLESS isLess = SI_STRLESS(); + // remove any copied strings and then the key typename TKeyVal::iterator iDelete; + bool bDeleted = false; do { iDelete = iKeyVal++; - DeleteString(iDelete->first.pItem); - DeleteString(iDelete->second); - iSection->second.erase(iDelete); + if(a_pValue == NULL || + (isLess(a_pValue, iDelete->second) == false && + isLess(iDelete->second, a_pValue) == false)) { + DeleteString(iDelete->first.pItem); + DeleteString(iDelete->second); + iSection->second.erase(iDelete); + bDeleted = true; + } } while (iKeyVal != iSection->second.end() && !IsLess(a_pKey, iKeyVal->first.pItem)); + if(!bDeleted) { + return false; + } + // done now if the section is not empty or we are not pruning away // the empty sections. Otherwise let it fall through into the section // deletion code diff --git a/snippets.cpp b/snippets.cpp index e2295fe..8a69aa6 100644 --- a/snippets.cpp +++ b/snippets.cpp @@ -101,8 +101,13 @@ snippets( // DELETING DATA - // deleting a key from a section. Optionally the entire - // section may be deleted if it is now empty. + // deleting a key with a value from a section. + // Optionally the entire section may be deleted if + // it is now empty. + ini.DeleteValue("section-name", "key-name", "value", + true /*delete the section if empty*/); + + // deleting a key with any value from a section. ini.Delete("section-name", "key-name", true /*delete the section if empty*/); diff --git a/testsi.cpp b/testsi.cpp index 609f328..4f7963e 100644 --- a/testsi.cpp +++ b/testsi.cpp @@ -73,6 +73,12 @@ Test( _tprintf(_T("\n-- Number of keys in section [standard] = %d\n"), ini.GetSectionSize(_T("standard"))); + // delete the key "foo" in section "standard", if it has value "bar" + ini.DeleteValue(_T("standard"), _T("foo"), _T("bar")); + pszVal = ini.GetValue(_T("standard"), _T("foo"), 0); + _tprintf(_T("\n-- Value of standard::foo is now '%s'\n"), + pszVal ? pszVal : _T("(null)")); + // delete the key "foo" in section "standard" ini.Delete(_T("standard"), _T("foo")); pszVal = ini.GetValue(_T("standard"), _T("foo"), 0); -- cgit v1.2.3