55 StringIMap::const_iterator k =
_keys.find(key);
132 StringIMap::iterator k =
_keys.find(key);
133 if (k !=
_keys.end()) {
142 std::pair<StringIMap::iterator, bool> result =
143 _keys.insert(std::make_pair(key, value));
146 _lines.back().key = result.first;
170 StringIMap::iterator k =
_keys.find(key);
171 if (k ==
_keys.end())
178 LineList::iterator line;
179 for (line =
_lines.begin(); line !=
_lines.end(); ++line) {
180 if (line->key == k) {
188 assert(found ==
true);
196 StringIMap::iterator k =
_keys.find(oldName);
197 if (k ==
_keys.end())
206 LineList::iterator line;
207 for (line =
_lines.begin(); line !=
_lines.end(); ++line)
212 assert(line !=
_lines.end());
221 std::pair<StringIMap::iterator, bool> result =
222 _keys.insert(std::make_pair(newName, value));
225 line->key = result.first;
231 for (LineList::const_iterator l = domain.
_lines.begin(); l != domain.
_lines.end(); ++l) {
232 if (l->key == domain.
_keys.end())
236 StringIMap::iterator k =
_keys.find(l->key->first);
237 if (k ==
_keys.end()) {
240 std::pair<StringIMap::iterator, bool> result =
241 _keys.insert(std::make_pair(l->key->first, l->key->second));
244 _lines.back().key = result.first;
251 k->second = l->key->second;
268 (!isalnum(c) && (c !=
'-') && (c !=
'_') && (c !=
'.') && (c !=
' ')))
289 int domainLineNumber = 0;
290 while (!stream.
eos()) {
298 UString key, value, lineComment;
299 parseConfigLine(line, domainName, key, value, lineComment, lineNumber);
301 if (!domainName.
empty()) {
310 throw Exception(
"\"%s\" isn't a valid domain name (line %d)",
311 domainName.
c_str(), lineNumber);
316 domain->_prologue = comment;
317 domain->_comment = lineComment;
322 domainLineNumber = lineNumber;
329 throw Exception(
"Found a key outside a domain (line %d)", lineNumber);
332 throw Exception(
"\"%s\" isn't a valid key name (line %d)",
333 key.
c_str(), lineNumber);
336 if (!comment.
empty())
340 addDomainKey(*domain, key, value, lineComment, lineNumber);
347 if (!lineComment.
empty()) {
348 if (!comment.
empty())
350 comment += lineComment;
355 if (!comment.
empty() && !stream.
eos()) {
376 if (!comment.
empty())
392 std::pair<StringIMap::iterator, bool> result =
393 domain.
_keys.insert(std::make_pair(key, value));
397 throw Exception(
"Duplicate key \"%s\" in domain \"%s\" (line %d)",
401 line.
key = result.first;
424 bool hasComment =
false;
436 }
else if (state == 2) {
447 if ((c ==
'#') || ((c ==
';') && (l == line.
begin()))) {
451 }
else if (c ==
'[') {
454 }
else if (c ==
']') {
456 throw Exception(
"Found extra ']' (line %d)", lineNumber);
457 }
else if (c ==
'=') {
471 throw Exception(
"Missing ']' (line %d)", lineNumber);
480 comment =
"# " + comment;
483 if (!domainName.
empty())
489 throw Exception(
"Value with a key (line %d)", lineNumber);
503 if (!(*domain)->_prologue.empty()) {
514 if (!(*domain)->_comment.empty()) {
522 for (ConfigDomain::LineList::const_iterator line = (*domain)->_lines.begin(); line != (*domain)->_lines.end(); ++line) {
524 if (line->key != (*domain)->_keys.end()) {
528 if (!line->comment.empty())
533 if (!line->comment.empty())
560 DomainMap::iterator domain =
_domainMap.find(name);
562 return domain->second;
568 DomainMap::const_iterator domain =
_domainMap.find(name);
570 return domain->second;
585 _domainMap.insert(std::make_pair(name, domain));
591 DomainMap::iterator domain =
_domainMap.find(name);
604 DomainMap::iterator domain =
_domainMap.find(oldName);
621 _domainMap.insert(std::make_pair(newName, d));
bool removeDomain(const UString &name)
void setDouble(const UString &key, double value)
bool renameDomain(const UString &oldName, const UString &newName)
virtual void flush()
Commit any buffered data to the underlying channel or storage medium; unbuffered streams can use the ...
void save(WriteStream &stream) const
A class holding an UTF-8 string.
void writeString(const UString &str)
Write the given string to the stream, encoded as UTF-8.
void reset(PointerType o=0)
Resets the pointer with the new value.
PointerType release()
Returns the plain pointer value and releases ScopedPtr.
UString composeString(T value)
Convert any POD integer, float/double or bool type into a string.
virtual bool eos() const =0
Returns true if a read failed because the stream has been reached.
void setString(const UString &key, const UString &value)
void load(SeekableReadStream &stream)
DomainList _domainList
List of domains in order.
void parseConfigLine(const UString &line, UString &domainName, UString &key, UString &value, UString &comment, int lineNumber)
UString getString(const UString &key, const UString &def="") const
ConfigDomain(const UString &name)
Utility templates and functions for working with strings and streams.
const DomainList & getDomains() const
StringIMap _keys
The key/value pairs of the config domain.
A simple scoped smart pointer template.
void exceptionDispatcherWarning(const char *s,...)
Exception dispatcher that prints the exception as a warning, and adds another reason on top...
Basic exceptions to throw.
UString readStringLine(SeekableReadStream &stream, Encoding encoding)
Read a line with the given encoding out of a stream.
utf8::iterator< std::string::const_iterator > iterator
const char * c_str() const
Return the (utf8 encoded) string data.
bool removeKey(const UString &key)
int getInt(const UString &key, int def=0) const
bool getKey(const UString &key, UString &value) const
A class storing a basic configuration file.
DomainMap _domainMap
Domains indexed by name.
LineList _lines
The lines of the config domain.
Basic writing stream interfaces.
Utility functions for working with differing string encodings.
bool empty() const
Is the string empty?
A scoped plain pointer, allowing pointer-y access and normal deletion.
void writeByte(byte value)
bool renameKey(const UString &oldName, const UString &newName)
Basic reading stream interfaces.
Generic interface for a writable data stream.
void setBool(const UString &key, bool value)
void setInt(const UString &key, int value)
double getDouble(const UString &key, double def=0.0) const
PointerType get() const
Returns the plain pointer value.
UString _prologue
Comments on top of the file.
void remove(const typename std::list< T *>::value_type &val)
static bool isASCII(uint32 c)
Is the character an ASCII character?
const UString & getName() const
Accessor for a domain (section) in a config file.
void set(const ConfigDomain &domain, bool clobber=true)
Add the keys of another domain.
bool hasDomain(const UString &name) const
bool getBool(const UString &key, bool def=false) const
A line in the config domain.
void clear()
Reset everything stored in this config file.
UString _epilogue
Comments at the bottom of the file.
void addDomainKey(ConfigDomain &domain, const UString &key, const UString &value, const UString &comment, int lineNumber)
ConfigDomain * getDomain(const UString &name)
void setKey(const UString &key, const UString &value)
void clear()
Clear the string's contents.
uint getUint(const UString &key, uint def=0) const
static bool isValidName(const UString &name)
Check whether the given string is a valid section or key name.
bool hasKey(const UString &key) const
Interface for a seekable & readable data stream.
void parseString(const UString &str, T &value, bool allowEmpty)
Parse a string into any POD integer, float/double or bool type.
UString comment
Line comment.
ConfigDomain * addDomain(const UString &name)
StringIMap::const_iterator key
Pointer to the key/value pair.
void setUint(const UString &key, uint value)