1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
#include <iostream>
#include <map>
#include <string>
namespace configuration
{
//---------------------------------------------------------------------------
// The configuration::data is a simple map string (key, value) pairs.
// The file is stored as a simple listing of those pairs, one per line.
// The key is separated from the value by an equal sign '='.
// Commentary begins with the first non-space character on the line a hash or
// semi-colon ('#' or ';').
//
// Example:
// # This is an example
// source.directory = C:\Documents and Settings\Jennifer\My Documents\
// file.types = *.jpg;*.gif;*.png;*.pix;*.tif;*.bmp
//
// Notice that the configuration file format does not permit values to span
// more than one line, commentary at the end of a line, or [section]s.
//
struct data: std::map <std::string, std::string>
{
// Here is a little convenience method...
bool iskey( const std::string& s ) const
{
return count( s ) != 0;
}
};
//---------------------------------------------------------------------------
// The extraction operator reads configuration::data until EOF.
// Invalid data is ignored.
//
std::istream& operator >> ( std::istream& ins, data& d )
{
std::string s, key, value;
// For each (key, value) pair in the file
while (std::getline( ins, s ))
{
std::string::size_type begin = s.find_first_not_of( " \f\t\v" );
// Skip blank lines
if (begin == std::string::npos) continue;
// Skip commentary
if (std::string( "#;" ).find( s[ begin ] ) != std::string::npos) continue;
// Extract the key value
std::string::size_type end = s.find( '=', begin );
key = s.substr( begin, end - begin );
// (No leading or trailing whitespace allowed)
key.erase( key.find_last_not_of( " \f\t\v" ) + 1 );
// No blank keys allowed
if (key.empty()) continue;
// Extract the value (no leading or trailing whitespace allowed)
begin = s.find_first_not_of( " \f\n\r\t\v", end + 1 );
end = s.find_last_not_of( " \f\n\r\t\v" ) + 1;
value = s.substr( begin, end - begin );
// Insert the properly extracted (key, value) pair into the map
d[ key ] = value;
}
return ins;
}
//---------------------------------------------------------------------------
// The insertion operator writes all configuration::data to stream.
//
std::ostream& operator << ( std::ostream& outs, const data& d )
{
data::const_iterator iter;
for (iter = d.begin(); iter != d.end(); iter++)
outs << iter->first << " = " << iter->last << endl;
return outs;
}
} // namespace configuration
|