An Overlay-based
Virtual Network Substrate
SpoVNet

source: source/ariba/utility/configuration/ConfigFile.cpp @ 8606

Last change on this file since 8606 was 7471, checked in by Christoph Mayer, 14 years ago
File size: 4.7 KB
Line 
1// [License]
2// ConfigFile.h
3// Class for reading named values from configuration files
4// Richard J. Wagner  v2.1  24 May 2004  wagnerr@umich.edu
5
6// Copyright (c) 2004 Richard J. Wagner
7//
8// Permission is hereby granted, free of charge, to any person obtaining a copy
9// of this software and associated documentation files (the "Software"), to
10// deal in the Software without restriction, including without limitation the
11// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12// sell copies of the Software, and to permit persons to whom the Software is
13// furnished to do so, subject to the following conditions:
14//
15// The above copyright notice and this permission notice shall be included in
16// all copies or substantial portions of the Software.
17//
18// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24// IN THE SOFTWARE.
25// [License]
26
27#include "ConfigFile.h"
28
29using std::string;
30
31namespace ariba {
32namespace utility {
33
34
35ConfigFile::ConfigFile( string filename, string delimiter,
36                        string comment, string sentry )
37        : myDelimiter(delimiter), myComment(comment), mySentry(sentry)
38{
39        // Construct a ConfigFile, getting keys and values from given file
40
41        std::ifstream in( filename.c_str() );
42
43        if( !in ) throw file_not_found( filename );
44
45        in >> (*this);
46}
47
48
49ConfigFile::ConfigFile()
50        : myDelimiter( string(1,'=') ), myComment( string(1,'#') )
51{
52        // Construct a ConfigFile without a file; empty
53}
54
55
56void ConfigFile::remove( const string& key )
57{
58        // Remove key and its value
59        myContents.erase( myContents.find( key ) );
60        return;
61}
62
63
64bool ConfigFile::keyExists( const string& key ) const
65{
66        // Indicate whether key is found
67        mapci p = myContents.find( key );
68        return ( p != myContents.end() );
69}
70
71
72/* static */
73void ConfigFile::trim( string& s )
74{
75        // Remove leading and trailing whitespace
76        static const char whitespace[] = " \n\t\v\r\f";
77        s.erase( 0, s.find_first_not_of(whitespace) );
78        s.erase( s.find_last_not_of(whitespace) + 1U );
79}
80
81
82std::ostream& operator<<( std::ostream& os, const ConfigFile& cf )
83{
84        // Save a ConfigFile to os
85        for( ConfigFile::mapci p = cf.myContents.begin();
86             p != cf.myContents.end();
87                 ++p )
88        {
89                os << p->first << " " << cf.myDelimiter << " ";
90                os << p->second << std::endl;
91        }
92        return os;
93}
94
95
96std::istream& operator>>( std::istream& is, ConfigFile& cf )
97{
98        // Load a ConfigFile from is
99        // Read in keys and values, keeping internal whitespace
100        typedef string::size_type pos;
101        const string& delim  = cf.myDelimiter;  // separator
102        const string& comm   = cf.myComment;    // comment
103        const string& sentry = cf.mySentry;     // end of file sentry
104        const pos skip = delim.length();        // length of separator
105
106        string nextline = "";  // might need to read ahead to see where value ends
107
108        while( is || nextline.length() > 0 )
109        {
110                // Read an entire line at a time
111                string line;
112                if( nextline.length() > 0 )
113                {
114                        line = nextline;  // we read ahead; use it now
115                        nextline = "";
116                }
117                else
118                {
119                        std::getline( is, line );
120                }
121
122                // Ignore comments
123                line = line.substr( 0, line.find(comm) );
124
125                // Check for end of file sentry
126                if( sentry != "" && line.find(sentry) != string::npos ) return is;
127
128                // Parse the line if it contains a delimiter
129                pos delimPos = line.find( delim );
130                if( delimPos < string::npos )
131                {
132                        // Extract the key
133                        string key = line.substr( 0, delimPos );
134                        line.replace( 0, delimPos+skip, "" );
135
136                        // See if value continues on the next line
137                        // Stop at blank line, next line with a key, end of stream,
138                        // or end of file sentry
139                        bool terminate = false;
140                        while( !terminate && is )
141                        {
142                                std::getline( is, nextline );
143                                terminate = true;
144
145                                string nlcopy = nextline;
146                                ConfigFile::trim(nlcopy);
147                                if( nlcopy == "" ) continue;
148
149                                nextline = nextline.substr( 0, nextline.find(comm) );
150                                if( nextline.find(delim) != string::npos )
151                                        continue;
152                                if( sentry != "" && nextline.find(sentry) != string::npos )
153                                        continue;
154
155                                nlcopy = nextline;
156                                ConfigFile::trim(nlcopy);
157                                if( nlcopy != "" ) line += "\n";
158                                line += nextline;
159                                terminate = false;
160                        }
161
162                        // Store key and value
163                        ConfigFile::trim(key);
164                        ConfigFile::trim(line);
165                        cf.myContents[key] = line;  // overwrites if key is repeated
166                }
167        }
168
169        return is;
170}
171
172}}
Note: See TracBrowser for help on using the repository browser.