File indexing completed on 2024-04-28 05:32:12

0001 /*
0002     this file is part of the oxygen gtk engine
0003     SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0004 
0005     inspired notably from kdelibs/kdeui/color/kcolorutils.h
0006     SPDX-FileCopyrightText: 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
0007     SPDX-FileCopyrightText: 2007 Thomas Zander <zander@kde.org>
0008     SPDX-FileCopyrightText: 2007 Zack Rusin <zack@kde.org>
0009 
0010     SPDX-License-Identifier: LGPL-2.0-or-later
0011 */
0012 
0013 #include "oxygenoptionmap.h"
0014 #include "config.h"
0015 
0016 #include <iostream>
0017 #include <fstream>
0018 
0019 namespace Oxygen
0020 {
0021 
0022     //_________________________________________________________
0023     OptionMap::OptionMap( const std::string& filename )
0024     {
0025 
0026         std::ifstream in( filename.c_str() );
0027         if( !in ) return;
0028 
0029         std::string currentSection;
0030         std::string currentLine;
0031         while( std::getline( in, currentLine, '\n' ) )
0032         {
0033 
0034             if( currentLine.empty() ) continue;
0035 
0036             // check if line is a section
0037             if( currentLine[0] == '[' )
0038             {
0039 
0040                 size_t end( currentLine.rfind( ']' ) );
0041                 if( end == std::string::npos ) continue;
0042                 currentSection = currentLine.substr( 0, end+1 );
0043 
0044             } else if( currentSection.empty() ) {
0045 
0046                 continue;
0047 
0048             }
0049 
0050             // check if line is a valid option
0051             size_t mid( currentLine.find( '=' ) );
0052             if( mid == std::string::npos ) continue;
0053 
0054             // insert new option in map
0055             Option option( currentLine.substr( 0, mid ), currentLine.substr( mid+1 ) );
0056 
0057             #if OXYGEN_DEBUG
0058             option.setFile( filename );
0059             #endif
0060 
0061             (*this)[currentSection].insert( option );
0062 
0063         }
0064 
0065     }
0066 
0067     //_________________________________________________________
0068     bool OptionMap::operator == (const OptionMap& other ) const
0069     {
0070         const_iterator firstIter( begin() );
0071         const_iterator secondIter( other.begin() );
0072         for(;firstIter != end() && secondIter != other.end(); ++firstIter, ++secondIter )
0073         {
0074             if( !( firstIter->first == secondIter->first && firstIter->second == secondIter->second ) )
0075             { return false; }
0076         }
0077 
0078         return firstIter == end() && secondIter == other.end();
0079     }
0080 
0081     //_________________________________________________________
0082     OptionMap& OptionMap::merge( const OptionMap& other )
0083     {
0084 
0085         // loop over source maps
0086         for( const_iterator iter = other.begin(); iter != other.end(); ++iter )
0087         {
0088 
0089             iterator source_iter( find( iter->first ) );
0090             if( source_iter == end() )
0091             {
0092 
0093                 // if section is not found in this map, insert it as a whole
0094                 insert( std::make_pair( iter->first, iter->second ) );
0095 
0096             } else {
0097 
0098                 // otherwise merge both sets
0099                 for( Option::Set::const_iterator optionIter = iter->second.begin(); optionIter != iter->second.end(); ++optionIter )
0100                 {
0101 
0102                     source_iter->second.erase( *optionIter );
0103                     source_iter->second.insert( *optionIter );
0104 
0105                 }
0106 
0107             }
0108         }
0109 
0110         return *this;
0111     }
0112 
0113     //_________________________________________________________
0114     bool OptionMap::hasOption( const std::string& section, const std::string& tag ) const
0115     {
0116         const_iterator iter( find( section ) );
0117         if( iter == end() ) return false;
0118 
0119         Option::Set::const_iterator optionIter( iter->second.find( Option(tag) ) );
0120         return optionIter != iter->second.end();
0121     }
0122 
0123     //_________________________________________________________
0124     Option OptionMap::getOption( const std::string& section, const std::string& tag ) const
0125     {
0126         const_iterator iter( find( section ) );
0127         if( iter == end() )
0128         {
0129             #if OXYGEN_DEBUG
0130             std::cerr << "Oxygen::OptionMap::getOption - could not find section " << section << std::endl;
0131             #endif
0132 
0133             return Option();
0134 
0135         }
0136 
0137         Option::Set::const_iterator optionIter( iter->second.find( Option(tag) ) );
0138         if( optionIter == iter->second.end() )
0139         {
0140             #if OXYGEN_DEBUG
0141             std::cerr << "Oxygen::OptionMap::getOption - could not find tag " << tag << std::endl;
0142             #endif
0143 
0144             return Option();
0145 
0146         } else {
0147 
0148             return *optionIter;
0149 
0150         }
0151     }
0152 
0153 }