added ConfigHandler from OLX (for reading a single option out of a ini-file)

git-svn-id: https://clonekeenplus.svn.sourceforge.net/svnroot/clonekeenplus/cgenius/trunk@144 4df4b0f3-56ce-47cb-b001-ed939b7d65a6
This commit is contained in:
albertzeyer
2009-07-24 14:12:24 +00:00
parent a82fedbcb2
commit 74aaa4e76f
2 changed files with 379 additions and 0 deletions

279
src/ConfigHandler.cpp Normal file
View File

@@ -0,0 +1,279 @@
/////////////////////////////////////////
//
// OpenLieroX
//
// Auxiliary Software class library
//
// based on the work of JasonB
// enhanced by Dark Charlie and Albert Zeyer
//
// code under LGPL
//
/////////////////////////////////////////
// Config file handler
// Created 30/9/01
// By Jason Boettcher
#include <map>
#include <string>
#include "ConfigHandler.h"
#include "FindFile.h"
#include "StringUtils.h"
#include "MathLib.h"
typedef std::map<std::string, int, stringcaseless> KeywordMap;
static KeywordMap Keywords;
// Internal
static bool GetString(const std::string& filename, const std::string& section, const std::string& key, std::string& string, bool abs_fn = false);
///////////////////
// Add a keyword to the list
bool AddKeyword(const std::string& key, int value)
{
Keywords[key] = value;
return true;
}
///////////////////
// Read a keyword from a file
bool ReadKeyword(const std::string& filename, const std::string& section, const std::string& key, int *value, int defaultv)
{
std::string string;
*value = defaultv;
if(!GetString(filename,section,key,string))
return false;
// Try and find a keyword with matching keys
KeywordMap::iterator f = Keywords.find(string);
if(f != Keywords.end()) {
//notes << filename << ":" << section << "." << key << ": " << f->first << "(" << string << ") = " << f->second << endl;
*value = f->second;
return true;
}
warnings << filename << ":" << section << "." << key << ": '" << string << "' is an unknown keyword" << endl;
return false;
}
///////////////////
// Read a keyword from a file (bool version)
bool ReadKeyword(const std::string& filename, const std::string& section, const std::string& key, bool *value, bool defaultv)
{
int v = defaultv ? 1 : 0;
bool ret = ReadKeyword(filename, section, key, &v, defaultv ? 1 : 0);
*value = v != 0;
return ret;
}
///////////////////
// Read bit flags specified by keywords from a file
bool ReadKeywordList(const std::string& filename, const std::string& section, const std::string& key, int *value, int defaultv)
{
std::string string;
*value = defaultv;
if(!GetString(filename,section,key,string))
return false;
std::vector<std::string> split = explode(string, ",");
for (std::vector<std::string>::iterator it = split.begin(); it != split.end(); it++) {
TrimSpaces(*it);
KeywordMap::iterator key = Keywords.find(*it);
if (key != Keywords.end())
*value |= key->second;
}
return true;
}
///////////////////
// Read an interger from a file
bool ReadInteger(const std::string& filename, const std::string& section, const std::string& key, int *value, int defaultv)
{
std::string string;
*value = defaultv;
if(!GetString(filename,section,key,string))
return false;
*value = from_string<int>(string);
return true;
}
///////////////////
// Read a string from a file
bool ReadString(const std::string& filename, const std::string& section, const std::string& key, std::string& value, std::string defaultv, bool abs_fn)
{
value = defaultv;
return GetString(filename,section,key,value, abs_fn);
/*int result = GetString(filename,section,key,value);
if (strlen(value) <= 0)
strcpy(value,defaultv);
return result;*/
}
///////////////////
// Read a float from a file
bool ReadFloat(const std::string& filename, const std::string& section, const std::string& key, float *value, float defaultv)
{
std::string string;
*value = defaultv;
if(!GetString(filename,section,key,string))
return false;
*value = (float)atof(string);
return true;
}
bool ReadColour(const std::string& filename, const std::string& section, const std::string& key, Color& value, const Color& defaultv) {
std::string string;
value = defaultv;
if(!GetString(filename,section,key,string))
return false;
value = StrToCol(string);
return true;
}
//////////////////
// Reads an array of integers
bool ReadIntArray(const std::string& filename, const std::string& section, const std::string& key, int *array, int num_items)
{
std::string string;
if (!GetString(filename,section,key,string))
return false;
std::vector<std::string> arr = explode(string,",");
for (register int i=0; i<MIN(num_items,(int)arr.size()); i++)
array[i] = from_string<int>(arr[i]);
return num_items == (int)arr.size();
}
///////////////////
// Read a string
static bool GetString(const std::string& filename, const std::string& section, const std::string& key, std::string& string, bool abs_fn)
{
FILE *config = NULL;
std::string Line;
std::string tmpLine;
std::string curSection;
std::string temp;
std::string curKey;
size_t chardest = 0;
int Position;
bool found = false;
if(filename == "")
return false;
if(abs_fn) {
config = fopen(filename.c_str(), "rt");
} else
config = OpenGameFile(filename,"rt");
if(!config)
return false;
//string="";
curSection="";
temp="";
curKey="";
// Check for UTF-8 encoded file and skip the UTF-8 mark if it is
unsigned char utf8mark[3] = {0,0,0};
if(fread(utf8mark, sizeof(utf8mark), 1, config) == 0) {
fclose(config);
return false;
}
if (utf8mark[0] != 0xEF || utf8mark[1] != 0xBB || utf8mark[2] != 0xBF)
fseek(config, 0, SEEK_SET); // Not a UTF-8 file, jump back to the beginning
while(!feof(config) && !ferror(config))
{
// Parse the lines
Line = ReadUntil(config, '\n');
TrimSpaces(Line);
///////////////////
// Comment, Ignore
if(Line.size() == 0 || Line[0] == '#')
continue;
////////////
// Sections
if(Line[0] == '[' && Line[Line.size()-1] == ']')
{
curSection = Line.substr(1);
curSection.erase(curSection.size()-1);
continue;
}
////////
// Keys
chardest = Line.find('=');
if(chardest != std::string::npos)
{
// Key
Position = (int)chardest;
tmpLine = Line;
tmpLine.erase(Position);
TrimSpaces(tmpLine);
curKey = tmpLine;
// Check if this is the key were looking for under the section were looking for
if(stringcasecmp(curKey,key) == 0 && stringcasecmp(curSection,section) == 0)
{
// Get the value
tmpLine = Line.substr(Position+1);
TrimSpaces(tmpLine);
string = tmpLine;
found = true;
break;
}
continue;
}
}
fclose(config);
return found;
}

100
src/ConfigHandler.h Normal file
View File

@@ -0,0 +1,100 @@
/////////////////////////////////////////
//
// OpenLieroX
//
// Auxiliary Software class library
//
// based on the work of JasonB
// enhanced by Dark Charlie and Albert Zeyer
//
// code under LGPL
//
/////////////////////////////////////////
// Config file handler
// Created 30/9/01
// By Jason Boettcher
#ifndef __CONFIGHANDLER_H__
#define __CONFIGHANDLER_H__
#include "CVec.h"
#include "StringUtils.h"
#include "MathLib.h"
#include <string>
#include <SDL.h>
#include <vector>
#define MAX_STRING_LENGTH 4096
#define MAX_MINOR_LENGTH 256
#define MAX_KEYWORDS 256
// Value reading
bool ReadString(const std::string& filename, const std::string& section, const std::string& key, std::string& value, std::string defaultv, bool abs_fn = false);
bool ReadInteger(const std::string& filename, const std::string& section, const std::string& key, int *value, int defaultv);
bool ReadFloat(const std::string& filename, const std::string& section, const std::string& key, float *value, float defaultv);
bool ReadIntArray(const std::string& filename, const std::string& section, const std::string& key, int *array, int num_items);
struct Color;
bool ReadColour(const std::string& filename, const std::string& section, const std::string& key, Color& value, const Color& defaultv);
template<typename T>
bool ReadArray(const std::string& filename, const std::string& section, const std::string& key, T* data, size_t num) {
std::string string;
if (!ReadString(filename,section,key,string,""))
return false;
std::vector<std::string> arr = explode(string,",");
for (size_t i=0; i< MIN(num,arr.size()); i++)
data[i] = from_string<T>(arr[i]);
return num == arr.size();
}
template<typename T>
bool ReadVectorD2(const std::string& filename, const std::string& section, const std::string& key, VectorD2<T>& v, VectorD2<T> defv = VectorD2<T>()) {
v = defv;
T _v[2] = {0,0};
if(!ReadArray(filename, section, key, _v, 2)) return false;
v.x = _v[0]; v.y = _v[1];
return true;
}
template<typename T>
bool ReadMatrixD2(const std::string& filename, const std::string& section, const std::string& key, MatrixD2<T>& v, MatrixD2<T> defv = MatrixD2<T>()) {
v = defv;
T _v[4] = {0,0,0,0};
if(!ReadArray(filename, section, key, _v, 4)) return false;
v.v1.x = _v[0]; v.v1.y = _v[1]; v.v2.x = _v[2]; v.v2.y = _v[3];
return true;
}
bool AddKeyword(const std::string& key, int value);
bool ReadKeyword(const std::string& filename, const std::string& section, const std::string& key, int *value, int defaultv);
bool ReadKeyword(const std::string& filename, const std::string& section, const std::string& key, bool *value, bool defaultv);
bool ReadKeywordList(const std::string& filename, const std::string& section, const std::string& key, int *value, int defaultv);
#endif // __CONFIGHANDLER_H__