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