ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/auterman/Demo/PATJetIDAnalyzer/bin/ConfigFile.cc
Revision: 1.1
Committed: Mon Feb 25 15:54:04 2008 UTC (17 years, 2 months ago) by auterman
Content type: text/plain
Branch point for: tex, JetID, Demo, MAIN
Log Message:
Initial revision

File Contents

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