From 74aaa4e76fb343a1192e9cc16a0f7f05e23476a9 Mon Sep 17 00:00:00 2001 From: albertzeyer Date: Fri, 24 Jul 2009 14:12:24 +0000 Subject: [PATCH] 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 --- src/ConfigHandler.cpp | 279 ++++++++++++++++++++++++++++++++++++++++++ src/ConfigHandler.h | 100 +++++++++++++++ 2 files changed, 379 insertions(+) create mode 100644 src/ConfigHandler.cpp create mode 100644 src/ConfigHandler.h diff --git a/src/ConfigHandler.cpp b/src/ConfigHandler.cpp new file mode 100644 index 000000000..b6d237f35 --- /dev/null +++ b/src/ConfigHandler.cpp @@ -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 +#include +#include "ConfigHandler.h" +#include "FindFile.h" +#include "StringUtils.h" +#include "MathLib.h" + + + +typedef std::map 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 split = explode(string, ","); + for (std::vector::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(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 arr = explode(string,","); + for (register int i=0; i(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; +} + + diff --git a/src/ConfigHandler.h b/src/ConfigHandler.h new file mode 100644 index 000000000..d0178a17a --- /dev/null +++ b/src/ConfigHandler.h @@ -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 +#include +#include + +#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 +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 arr = explode(string,","); + for (size_t i=0; i< MIN(num,arr.size()); i++) + data[i] = from_string(arr[i]); + + return num == arr.size(); +} + +template +bool ReadVectorD2(const std::string& filename, const std::string& section, const std::string& key, VectorD2& v, VectorD2 defv = VectorD2()) { + 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 +bool ReadMatrixD2(const std::string& filename, const std::string& section, const std::string& key, MatrixD2& v, MatrixD2 defv = MatrixD2()) { + 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__