1
0
forked from 0ad/0ad

Config Database, initial commit

This was SVN commit r443.
This commit is contained in:
Simon Brenner 2004-06-09 13:53:32 +00:00
parent ca523e9f3c
commit 8b617e732b
2 changed files with 210 additions and 0 deletions

130
source/ps/ConfigDB.cpp Executable file
View File

@ -0,0 +1,130 @@
#include "Prometheus.h"
#include "Parser.h"
#include "ConfigDB.h"
#include "CLogger.h"
#include "res/vfs.h"
#include "res/file.h"
using namespace std;
typedef map <CStr, CConfigValue> TConfigMap;
TConfigMap CConfigDB::m_Map[CFG_LAST];
CStr CConfigDB::m_ConfigFile[CFG_LAST];
bool CConfigDB::m_UseVFS[CFG_LAST];
CConfigValue *CConfigDB::GetValue(EConfigNamespace ns, CStr name)
{
assert(ns < CFG_LAST && ns >= 0);
TConfigMap::iterator it=m_Map[ns].find(name);
if (it == m_Map[ns].end())
return NULL;
else
return &(it->second);
}
CConfigValue *CConfigDB::CreateValue(EConfigNamespace ns, CStr name)
{
assert(ns < CFG_LAST && ns >= 0);
CConfigValue *ret=GetValue(ns, name);
if (ret) return ret;
TConfigMap::iterator it=m_Map[ns].insert(m_Map[ns].begin(), make_pair(name, CConfigValue()));
return &(it->second);
}
void CConfigDB::SetConfigFile(EConfigNamespace ns, bool useVFS, CStr path)
{
assert(ns < CFG_LAST && ns >= 0);
m_ConfigFile[ns]=path;
m_UseVFS[ns]=useVFS;
}
bool CConfigDB::Reload(EConfigNamespace ns)
{
// Set up CParser
CParser parser;
CParserLine parserLine;
parser.InputTaskType("Assignment", "_$ident_=_[-$arg(_minus)]_$value_[;$rest]");
parser.InputTaskType("Comment", "_;$rest");
void *buffer;
uint buflen;
File f;
Handle fh;
if (m_UseVFS[ns])
{
// Open file with VFS
fh=vfs_load(m_ConfigFile[ns], buffer, buflen);
if (fh <= 0)
{
LOG(ERROR, "vfs_load for \"%s\" failed: return was %lld", m_ConfigFile[ns].c_str(), fh);
return false;
}
}
else
{
if (file_open(m_ConfigFile[ns].c_str(), 0, &f)!=0)
{
LOG(ERROR, "file_open for \"%s\" failed", m_ConfigFile[ns].c_str());
return false;
}
if (file_map(&f, buffer, buflen) != 0)
{
LOG(ERROR, "file_map for \"%s\" failed", m_ConfigFile[ns].c_str());
return false;
}
}
TConfigMap newMap;
char *filebuf=(char *)malloc(buflen+1);
memcpy(filebuf, buffer, buflen);
filebuf[buflen]=0;
// Read file line by line
char *ctxt=NULL;
// strtok is defined to skip empty tokens, so this neatly takes care of
// unix/windows file endings
const char *delim="\r\n";
char *line=strtok_r((char *)filebuf, delim, &ctxt);
do
{
// Send line to parser
parserLine.ParseString(parser, line);
// Get name and value from parser
string name;
string value;
if (parserLine.GetArgCount()>=2 &&
parserLine.GetArgString(0, name) &&
parserLine.GetArgString(1, value))
{
// Add name and value to the map
newMap[name].m_String=value;
LOG(NORMAL, "Loaded config string \"%s\" = \"%s\"", name.c_str(), value.c_str());
}
}
while (line = strtok_r(NULL, delim, &ctxt));
m_Map[ns].swap(newMap);
free(filebuf);
// Close the correct file handle
if (m_UseVFS[ns])
{
vfs_close(fh);
}
else
{
file_unmap(&f);
file_close(&f);
}
}
void CConfigDB::WriteFile(EConfigNamespace ns, bool useVFS, CStr path)
{
// TODO Implement this function
}

80
source/ps/ConfigDB.h Executable file
View File

@ -0,0 +1,80 @@
/*
CConfigDB - Load, access and store configuration variables
TDD : http://forums.wildfiregames.com/0ad/index.php?showtopic=1125
AUTHOR : Simon Brenner <simon@wildfiregames.com>, <simon.brenner@home.se>
OVERVIEW:
*/
#ifndef _ps_ConfigDB_H
#define _ps_ConfigDB_H
#include "Prometheus.h"
#include "Parser.h"
#include "CStr.h"
#include "Singleton.h"
enum EConfigNamespace
{
CFG_SYSTEM,
CFG_MOD,
CFG_USER,
CFG_LAST
};
typedef CParserValue CConfigValue;
#define g_ConfigDB CConfigDB::GetSingleton()
class CConfigDB: public Singleton<CConfigDB>
{
static std::map <CStr, CConfigValue> m_Map[];
static CStr m_ConfigFile[];
static bool m_UseVFS[];
public:
// GetValue()
// Attempt to find a config variable with the given name in the specified
// namespace.
//
// Returns a pointer to the config value structure for the variable, or
// NULL if such a variable could not be found
CConfigValue *GetValue(EConfigNamespace ns, CStr name);
// CreateValue()
// Create a new config value in the specified namespace. If such a
// variable already exists, the old value is returned and the effect is
// exactly the same as that of GetValue()
//
// Returns a pointer to the value of the newly created config variable, or
// that of the already existing config variable.
CConfigValue *CreateValue(EConfigNamespace ns, CStr name);
// SetConfigFile()
// Set the path to the config file used to populate the specified namespace
// Note that this function does not actually load the config file. Use
// the Reload() method if you want to read the config file at the same time.
//
// 'path': The path to the config file.
// VFS: relative to VFS root
// non-VFS: relative to current working directory (binaries/data/)
// 'useVFS': true if the path is a VFS path, false if it is a real path
void SetConfigFile(EConfigNamespace ns, bool useVFS, CStr path);
// Reload()
// Reload the config file associated with the specified config namespace
// (the last config file path set with SetConfigFile)
//
// Returns:
// true: if the reload succeeded,
// false: if the reload failed
bool Reload(EConfigNamespace);
// WriteFile()
// Write the current state of the specified config namespace to the file
// specified by 'path'
//
// This function can also
void WriteFile(EConfigNamespace ns, bool useVFS, CStr path);
};
#endif