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

Last change on this file since 3712 was 3690, checked in by mies, 15 years ago

Merged 20090512-mies-connectors changes r3472:r3689 into trunk.

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
31ConfigFile::ConfigFile( string filename, string delimiter,
32 string comment, string sentry )
33 : myDelimiter(delimiter), myComment(comment), mySentry(sentry)
34{
35 // Construct a ConfigFile, getting keys and values from given file
36
37 std::ifstream in( filename.c_str() );
38
39 if( !in ) throw file_not_found( filename );
40
41 in >> (*this);
42}
43
44
45ConfigFile::ConfigFile()
46 : myDelimiter( string(1,'=') ), myComment( string(1,'#') )
47{
48 // Construct a ConfigFile without a file; empty
49}
50
51
52void ConfigFile::remove( const string& key )
53{
54 // Remove key and its value
55 myContents.erase( myContents.find( key ) );
56 return;
57}
58
59
60bool ConfigFile::keyExists( const string& key ) const
61{
62 // Indicate whether key is found
63 mapci p = myContents.find( key );
64 return ( p != myContents.end() );
65}
66
67
68/* static */
69void ConfigFile::trim( string& s )
70{
71 // Remove leading and trailing whitespace
72 static const char whitespace[] = " \n\t\v\r\f";
73 s.erase( 0, s.find_first_not_of(whitespace) );
74 s.erase( s.find_last_not_of(whitespace) + 1U );
75}
76
77
78std::ostream& operator<<( std::ostream& os, const ConfigFile& cf )
79{
80 // Save a ConfigFile to os
81 for( ConfigFile::mapci p = cf.myContents.begin();
82 p != cf.myContents.end();
83 ++p )
84 {
85 os << p->first << " " << cf.myDelimiter << " ";
86 os << p->second << std::endl;
87 }
88 return os;
89}
90
91
92std::istream& operator>>( std::istream& is, ConfigFile& cf )
93{
94 // Load a ConfigFile from is
95 // Read in keys and values, keeping internal whitespace
96 typedef string::size_type pos;
97 const string& delim = cf.myDelimiter; // separator
98 const string& comm = cf.myComment; // comment
99 const string& sentry = cf.mySentry; // end of file sentry
100 const pos skip = delim.length(); // length of separator
101
102 string nextline = ""; // might need to read ahead to see where value ends
103
104 while( is || nextline.length() > 0 )
105 {
106 // Read an entire line at a time
107 string line;
108 if( nextline.length() > 0 )
109 {
110 line = nextline; // we read ahead; use it now
111 nextline = "";
112 }
113 else
114 {
115 std::getline( is, line );
116 }
117
118 // Ignore comments
119 line = line.substr( 0, line.find(comm) );
120
121 // Check for end of file sentry
122 if( sentry != "" && line.find(sentry) != string::npos ) return is;
123
124 // Parse the line if it contains a delimiter
125 pos delimPos = line.find( delim );
126 if( delimPos < string::npos )
127 {
128 // Extract the key
129 string key = line.substr( 0, delimPos );
130 line.replace( 0, delimPos+skip, "" );
131
132 // See if value continues on the next line
133 // Stop at blank line, next line with a key, end of stream,
134 // or end of file sentry
135 bool terminate = false;
136 while( !terminate && is )
137 {
138 std::getline( is, nextline );
139 terminate = true;
140
141 string nlcopy = nextline;
142 ConfigFile::trim(nlcopy);
143 if( nlcopy == "" ) continue;
144
145 nextline = nextline.substr( 0, nextline.find(comm) );
146 if( nextline.find(delim) != string::npos )
147 continue;
148 if( sentry != "" && nextline.find(sentry) != string::npos )
149 continue;
150
151 nlcopy = nextline;
152 ConfigFile::trim(nlcopy);
153 if( nlcopy != "" ) line += "\n";
154 line += nextline;
155 terminate = false;
156 }
157
158 // Store key and value
159 ConfigFile::trim(key);
160 ConfigFile::trim(line);
161 cf.myContents[key] = line; // overwrites if key is repeated
162 }
163 }
164
165 return is;
166}
Note: See TracBrowser for help on using the repository browser.