//---------------------------------------------------------------------------- // EgalTech 2015-2022 //---------------------------------------------------------------------------- // File : EGnStringKeyVal.h Data : 13.05.22 Versione : 2.4e2 // Contenuto : Funzioni per gestione coppie chiave-valore in stringhe. // // // // Modifiche : 23.05.15 DS Creazione modulo. // 27.11.18 DS Aggiunte Set/Get/RemoveValInNotes. // 13.05.22 DS In SetValInNotes e GetValInNotes aggiunta gestione separatore ':'. // //---------------------------------------------------------------------------- #pragma once #include "/EgtDev/Include/EGnStringUtils.h" //---------------------------------------------------------------------------- static const char EQUAL = '=' ; static const char COLON = ':' ; //---------------------------------------------------------------------------- inline bool IsValidKey( const std::string& sKey, bool bFull = false) { return ( ! sKey.empty() && sKey.find( '\n') == std::string::npos && (( bFull && ( sKey.back() == EQUAL || sKey.back() == COLON)) || sKey.find( EQUAL) == std::string::npos) && sKey.find_first_not_of( " \t\r\n") != std::string::npos) ; } //---------------------------------------------------------------------------- inline bool FindKey( const std::string& sString, const std::string& sKey, bool bFull = false) { if ( sString.empty() || ! IsValidKey( sKey, bFull)) return false ; return ( sString.compare( 0, sKey.length(), sKey) == 0 && ( bFull || ( sString.length() > sKey.length() && sString[sKey.length()] == EQUAL))) ; } //---------------------------------------------------------------------------- inline bool IsValidVal( const std::string& sString) { return ( sString.empty() || ( sString.find( '\n') == std::string::npos && sString.find_first_not_of( " \t\r\n") != std::string::npos)) ; } //---------------------------------------------------------------------------- inline bool ValidateVal( std::string& sString) { std::string::size_type i ; while ( ( i = sString.find_first_of( "\t\r\n")) != std::string::npos) sString[i] = '_' ; return true ; } //---------------------------------------------------------------------------- inline bool SetVal( const std::string& sKey, const std::string& sVal, std::string& sString) { if ( ! IsValidKey( sKey) || ! IsValidVal( sVal)) return false ; sString = sKey + EQUAL + sVal ; return true ; } //---------------------------------------------------------------------------- template inline bool SetVal( const std::string& sKey, T& Val, std::string& sString) { return SetVal( sKey, ToString( Val), sString) ; } //---------------------------------------------------------------------------- inline bool GetVal( const std::string& sString, const std::string& sKey, std::string& sVal) { if ( ! FindKey( sString, sKey)) return false ; sVal = sString.substr( sKey.length() + 1) ; return true ; } //---------------------------------------------------------------------------- template inline bool GetVal( const std::string& sString, const std::string& sKey, T& Val) { std::string sVal ; return ( GetVal( sString, sKey, sVal) && FromString( sVal, Val)) ; } //---------------------------------------------------------------------------- inline bool SetValInNotes( const std::string& sKey, const std::string& sVal, std::string& sNotes) { // verifiche validità chiave if ( ! IsValidKey( sKey) || ! IsValidVal( sVal)) return false ; // chiave con carattere finale speciale std::string sTkey = sKey ; if ( sKey.back() != COLON) sTkey += EQUAL ; // ricerca se già presente STRVECTOR vsTokens ; Tokenize( sNotes, ";", vsTokens) ; bool bFound = false ; for ( auto& sToken : vsTokens) { if ( FindKey( sToken, sTkey, true)) { sToken = sTkey + sVal ; bFound = true ; break ; } } // altrimenti aggiunta if ( ! bFound) vsTokens.emplace_back( sTkey + sVal) ; // ricostruzione delle note sNotes.clear() ; for ( const auto& sToken : vsTokens) { if ( ! IsEmptyOrSpaces( sToken)) sNotes += sToken + ";" ; } return true ; } //---------------------------------------------------------------------------- template inline bool SetValInNotes( const std::string& sKey, T& Val, std::string& sNotes) { return SetValInNotes( sKey, ToString( Val), sNotes) ; } //---------------------------------------------------------------------------- inline bool GetValInNotes( const std::string& sNotes, const std::string& sKey, std::string& sVal) { // verifiche validità chiave if ( sNotes.empty() || ! IsValidKey( sKey)) return false ; // chiave con carattere finale speciale std::string sTkey = sKey ; if ( sKey.back() != COLON) sTkey += EQUAL ; // ricerca STRVECTOR vsTokens ; Tokenize( sNotes, ";", vsTokens) ; for ( const auto& sToken : vsTokens) { if ( FindKey( sToken, sTkey, true)) { sVal = sToken.substr( sTkey.length()) ; return true ; } } return false ; } //---------------------------------------------------------------------------- template inline bool GetValInNotes( const std::string& sNotes, const std::string& sKey, T& Val) { std::string sVal ; return ( GetValInNotes( sNotes, sKey, sVal) && FromString( sVal, Val)) ; } //---------------------------------------------------------------------------- inline bool RemoveValInNotes( const std::string& sKey, std::string& sNotes) { // verifiche validità chiave if ( sNotes.empty() || ! IsValidKey( sKey)) return false ; // chiave con carattere finale speciale std::string sTkey = sKey ; if ( sKey.back() != COLON) sTkey += EQUAL ; // ricerca STRVECTOR vsTokens ; Tokenize( sNotes, ";", vsTokens) ; bool bFound = false ; for ( size_t i = 0; i < vsTokens.size() ; ++ i) { if ( FindKey( vsTokens[i], sTkey, true)) { vsTokens.erase( vsTokens.begin() + i) ; bFound = true ; break ; } } // se trovato e cancellato, devo ricostruire le note if ( bFound) { sNotes.clear() ; for ( const auto& sToken : vsTokens) { if ( ! IsEmptyOrSpaces( sToken)) sNotes += sToken + ";" ; } } return true ; }