#include <configfile.h>
The configFile class is a file-handling class which simplifies the use of configuration files. It is designed to read in a text file, which is in the following format:
% comment lines are preceded by % characters % all other lines are in the form " name = value " name1 = value1 parameter1 = 25 parameter2 = 35 this is a name = this is a value Any String Length With Any ^&(^ character = Any String Value &^#% %The name and the value are delimited by the = sign.
The name-value pairs can then be looked up. Using the class is simple: simply
create it by passing the name of the configuration file into the constructor,
and then use the lookUpValue public member function to look up specific name-value
pairs. Note that since the class is derived from ifstream
, not
fstream
, you can't write to the file from your program. The configuration
file must be edited externally, or opened up like any other file using the fstream
class.
Silly me: I didn't name the class DML_configFile: it's just named configFile.
It would be easy to change... just change all the names in the /dexter/DML_LIB/DML_configfile
directory, and change the syntax in /dexter/jedi/jedi.cpp and /dexter/cforce/cforce.cpp...
Those are the only two files that currently use it.
int nPairs
configFile( const char * ) ~configFile() String getName( int ) getName( int, char * ) String getValue( int ) getValue( int, char * ) String lookUpValue( char * ) String lookUpValue( String ) int lookUpValueBuf( char * name, char * buf )
ifstream, String classes
#include <configfile.h> configFile( const char * )
This constructor is more involved than most. First, it passes the argument
to its base class, ifstream
, which takes care of opening the file
and such details. Then, it does a bit of memory allocation and set-up, which
should be fairly self-explanatory.
The constructor proceeds to parse the config file line-by-line, by using the
peek()
member function (of ifstream
). If it finds
a % character or a newline, it skips the line (either it's blank or it's a comment).
Otherwise, it separates the line into a 'Before-the-Equals-Sign' string and
an 'After-the-Equals-Sign' string. These halves of the string will become the
'name' and 'value', respectively. If there is no equals sign, (i.e. there was
a newline before an equals sign), it prints an error and ignores both
the incorrect line and all lines until the next equals sign,
which it also ignores. Thus, a formatting error always results
in ignoring the incorrect line and the next correct line. A side effect.
If the array of name-value pairs isn't large enough, it is then re-sized and re-created. Note also that all the name-value pairs are stored in lower-case. This is for easy comparison later.
Because the constructor immediately closes the file, I probably should have made ifstream a private base class, rather than a public one. That could be very easily changed: just change the header file and recompile everything.
ifstream, istream, istream::peek
#include <configfile.h> configFile::~configFile()
#include <configfile.h> String configFile::getName( int ) configFile::getName( int, char * buf )
This function just extracts one of the names from the name-value pairs, according to the input. If the input is a 0, it extracts the first element in the array, 1 for the second, 2 for the third, etc, in standard array notation. Note that it makes a copy of the data and returns the copy... The data itself (within the class) can't be accessed with this function: it is read-only.
The second form of the function returns the information in the supplied buffer pointer, rather than returning a String class variable, and is therefore much faster. Do not pass this function a NULL pointer.
#include <configfile.h> String configFile::getValue( int ) configFile::getValue( int, char *buf )
#include <configfile.h> String configFile::lookUpValue( String theName ) String configFile::lookUpValue( char * ) configFile::lookUpValueBuf( char * theName, char * buf )
The lookUpValue functions take an input argument of the desired 'name' of the name-value pair in the config file, and return the associated value String, if any. They differ only in the argument and return formats, but all do exactly the same thing. It is important to note that this function overwrites the argument with a lower-case version. It is therefore case-insensitive. Say you had a config file which looked like this:
%This is a test config file. param # 1 = hello there Param # 2 = Hello Again! param3 = Good Morning!
And you wanted to look up some configuration paramters. The lookUpValue function works like this:
lookUpValue( "param # 1" )
, lookUpValue( "Param
# 1")
, and lookUpValue( "PaRaM # 1")
all
return the same value ("hello there"), but lookUpValue( "param
#1")
does NOT, since it is missing the space between '#' and '1'.
In the first two cases, the input string gets re-written to "param # 1",
and in the last, re-written to "param #1". This is not a big deal
if you're just putting code-written strings in there, but it becomes important
if you're going to pass in variables. One important thing to note: this function
will NOT accept a const char * argument.