[8645] Cleanup code for config loading/store/access.

Signed-off-by: VladimirMangos <vladimir@getmangos.com>
This commit is contained in:
XTZGZoReX 2009-10-14 20:46:22 +04:00 committed by VladimirMangos
parent 4d3e43e814
commit aff1a3e59f
9 changed files with 532 additions and 474 deletions

View file

@ -398,8 +398,8 @@ int Master::Run()
bool Master::_StartDB() bool Master::_StartDB()
{ {
///- Get world database info from configuration file ///- Get world database info from configuration file
std::string dbstring; std::string dbstring = sConfig.GetStringDefault("WorldDatabaseInfo", "");
if(!sConfig.GetString("WorldDatabaseInfo", &dbstring)) if(dbstring.empty())
{ {
sLog.outError("Database not specified in configuration file"); sLog.outError("Database not specified in configuration file");
return false; return false;
@ -416,7 +416,8 @@ bool Master::_StartDB()
if(!WorldDatabase.CheckRequiredField("db_version",REVISION_DB_MANGOS)) if(!WorldDatabase.CheckRequiredField("db_version",REVISION_DB_MANGOS))
return false; return false;
if(!sConfig.GetString("CharacterDatabaseInfo", &dbstring)) dbstring = sConfig.GetStringDefault("CharacterDatabaseInfo", "");
if(dbstring.empty())
{ {
sLog.outError("Character Database not specified in configuration file"); sLog.outError("Character Database not specified in configuration file");
return false; return false;
@ -434,7 +435,8 @@ bool Master::_StartDB()
return false; return false;
///- Get login database info from configuration file ///- Get login database info from configuration file
if(!sConfig.GetString("LoginDatabaseInfo", &dbstring)) dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", "");
if(dbstring.empty())
{ {
sLog.outError("Login database not specified in configuration file"); sLog.outError("Login database not specified in configuration file");
return false; return false;

View file

@ -50,7 +50,7 @@ char serviceDescription[] = "Massive Network Game Object Server";
int m_ServiceStatus = -1; int m_ServiceStatus = -1;
#endif #endif
bool StartDB(std::string &dbstring); bool StartDB();
void UnhookSignals(); void UnhookSignals();
void HookSignals(); void HookSignals();
@ -187,8 +187,7 @@ extern int main(int argc, char **argv)
} }
///- Initialize the database connection ///- Initialize the database connection
std::string dbstring; if(!StartDB())
if(!StartDB(dbstring))
return 1; return 1;
///- Get the list of realms for the server ///- Get the list of realms for the server
@ -312,9 +311,10 @@ void OnSignal(int s)
} }
/// Initialize connection to the database /// Initialize connection to the database
bool StartDB(std::string &dbstring) bool StartDB()
{ {
if(!sConfig.GetString("LoginDatabaseInfo", &dbstring)) std::string dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", "");
if(dbstring.empty())
{ {
sLog.outError("Database not specified"); sLog.outError("Database not specified");
return false; return false;

View file

@ -21,17 +21,16 @@
INSTANTIATE_SINGLETON_1(Config); INSTANTIATE_SINGLETON_1(Config);
Config::Config() : mIgnoreCase(true), mConf(NULL) Config::Config()
: mIgnoreCase(true), mConf(NULL)
{ {
} }
Config::~Config() Config::~Config()
{ {
delete mConf; delete mConf;
} }
bool Config::SetSource(const char *file, bool ignorecase) bool Config::SetSource(const char *file, bool ignorecase)
{ {
mIgnoreCase = ignorecase; mIgnoreCase = ignorecase;
@ -46,7 +45,7 @@ bool Config::Reload()
mConf = new DOTCONFDocument(mIgnoreCase ? mConf = new DOTCONFDocument(mIgnoreCase ?
DOTCONFDocument::CASEINSENSETIVE : DOTCONFDocument::CASEINSENSETIVE :
DOTCONFDocument::CASESENSETIVE); DOTCONFDocument::CASESENSITIVE);
if (mConf->setContent(mFilename.c_str()) == -1) if (mConf->setContent(mFilename.c_str()) == -1)
{ {
@ -58,117 +57,58 @@ bool Config::Reload()
return true; return true;
} }
bool Config::GetString(const char* name, std::string *value)
{
if(!mConf)
return false;
DOTCONFDocumentNode const *node = mConf->findNode(name);
if(!node || !node->getValue())
return false;
*value = node->getValue();
return true;
}
bool Config::GetString(const char* name, char const **value)
{
if(!mConf)
return false;
DOTCONFDocumentNode const *node = mConf->findNode(name);
if(!node || !node->getValue())
return false;
*value = node->getValue();
return true;
}
std::string Config::GetStringDefault(const char* name, const char* def) std::string Config::GetStringDefault(const char* name, const char* def)
{ {
if(!mConf) if (!mConf)
return std::string(def); return std::string(def);
DOTCONFDocumentNode const *node = mConf->findNode(name); DOTCONFDocumentNode const *node = mConf->findNode(name);
if(!node || !node->getValue()) if (!node || !node->getValue())
return std::string(def); return std::string(def);
return std::string(node->getValue()); return std::string(node->getValue());
} }
bool Config::GetBoolDefault(const char* name, bool def)
bool Config::GetBool(const char* name, bool *value)
{ {
if(!mConf) if (!mConf)
return false; return def;
DOTCONFDocumentNode const *node = mConf->findNode(name); DOTCONFDocumentNode const *node = mConf->findNode(name);
if(!node || !node->getValue()) if (!node || !node->getValue())
return false; return def;
const char* str = node->getValue(); const char* str = node->getValue();
if(strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 || if (strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 ||
strcmp(str, "yes") == 0 || strcmp(str, "YES") == 0 || strcmp(str, "yes") == 0 || strcmp(str, "YES") == 0 ||
strcmp(str, "1") == 0) strcmp(str, "1") == 0)
{ return true;
*value = true;
}
else else
*value = false;
return true;
}
bool Config::GetBoolDefault(const char* name, const bool def)
{
bool val;
return GetBool(name, &val) ? val : def;
}
bool Config::GetInt(const char* name, int *value)
{
if(!mConf)
return false; return false;
}
int32 Config::GetIntDefault(const char* name, int32 def)
{
if (!mConf)
return def;
DOTCONFDocumentNode const *node = mConf->findNode(name); DOTCONFDocumentNode const *node = mConf->findNode(name);
if(!node || !node->getValue()) if (!node || !node->getValue())
return false; return def;
*value = atoi(node->getValue()); return atoi(node->getValue());
return true;
} }
bool Config::GetFloat(const char* name, float *value) float Config::GetFloatDefault(const char* name, float def)
{ {
if(!mConf) if (!mConf)
return false; return def;
DOTCONFDocumentNode const *node = mConf->findNode(name); DOTCONFDocumentNode const *node = mConf->findNode(name);
if(!node || !node->getValue()) if (!node || !node->getValue())
return false; return def;
*value = atof(node->getValue()); return atof(node->getValue());
return true;
}
int Config::GetIntDefault(const char* name, const int def)
{
int val;
return GetInt(name, &val) ? val : def;
}
float Config::GetFloatDefault(const char* name, const float def)
{
float val;
return (GetFloat(name, &val) ? val : def);
} }

View file

@ -27,27 +27,22 @@ class DOTCONFDocument;
class MANGOS_DLL_SPEC Config class MANGOS_DLL_SPEC Config
{ {
public: public:
Config(); Config();
~Config(); ~Config();
bool SetSource(const char *file, bool ignorecase = true); bool SetSource(const char *file, bool ignorecase = true);
bool Reload(); bool Reload();
bool GetString(const char* name, std::string *value);
bool GetString(const char* name, char const **value);
std::string GetStringDefault(const char* name, const char* def); std::string GetStringDefault(const char* name, const char* def);
bool GetBool(const char* name, bool *value);
bool GetBoolDefault(const char* name, const bool def = false); bool GetBoolDefault(const char* name, const bool def = false);
int32 GetIntDefault(const char* name, const int32 def);
bool GetInt(const char* name, int *value);
int GetIntDefault(const char* name, const int def);
bool GetFloat(const char* name, float *value);
float GetFloatDefault(const char* name, const float def); float GetFloatDefault(const char* name, const float def);
std::string GetFilename() const { return mFilename; } std::string GetFilename() const { return mFilename; }
private: private:
std::string mFilename; std::string mFilename;
bool mIgnoreCase; bool mIgnoreCase;
DOTCONFDocument *mConf; DOTCONFDocument *mConf;

View file

@ -1,64 +1,68 @@
#include "Common.h" #include "Common.h"
#include "dotconfpp.h" #include "dotconfpp.h"
#ifdef WIN32 #ifdef WIN32
#define PATH_MAX _MAX_PATH # define PATH_MAX _MAX_PATH
#define strcasecmp stricmp # define strcasecmp stricmp
#define realpath(path,resolved_path) _fullpath(resolved_path, path, _MAX_PATH) # define realpath(path,resolved_path) _fullpath(resolved_path, path, _MAX_PATH)
#include <io.h> # include <io.h>
#else #else
#include <unistd.h> # include <unistd.h>
#include <limits.h> # include <limits.h>
#include <stdint.h> # include <stdint.h>
#include <strings.h> # include <strings.h>
#endif #endif
#if !defined(R_OK) #if !defined(R_OK)
#define R_OK 04 # define R_OK 04
#endif #endif
DOTCONFDocumentNode::DOTCONFDocumentNode():previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL), DOTCONFDocumentNode::DOTCONFDocumentNode()
values(NULL), valuesCount(0), : previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL),
name(NULL), lineNum(0), fileName(NULL), closed(true) values(NULL), valuesCount(0), name(NULL), lineNum(0),
fileName(NULL), closed(true)
{ {
} }
DOTCONFDocumentNode::~DOTCONFDocumentNode() DOTCONFDocumentNode::~DOTCONFDocumentNode()
{ {
free(name); free(name);
if(values != NULL){
for(int i = 0 ; i < valuesCount; i++){ if (values != NULL)
{
for (int i = 0; i < valuesCount; ++i)
free(values[i]); free(values[i]);
}
free(values); free(values);
} }
} }
void DOTCONFDocumentNode::pushValue(char * _value) void DOTCONFDocumentNode::pushValue(char* _value)
{ {
++valuesCount; ++valuesCount;
values = (char**)realloc(values, valuesCount*sizeof(char*)); values = (char**)realloc(values, valuesCount * sizeof(char*));
values[valuesCount-1] = strdup(_value); values[valuesCount - 1] = strdup(_value);
} }
const char* DOTCONFDocumentNode::getValue(int index) const const char* DOTCONFDocumentNode::getValue(int index) const
{ {
if(index >= valuesCount){ if (index >= valuesCount)
return NULL; return NULL;
}
return values[index]; return values[index];
} }
DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity): DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity)
mempool(NULL), : mempool(NULL), curParent(NULL), curPrev(NULL), curLine(0), file(NULL), fileName(NULL)
curParent(NULL), curPrev(NULL), curLine(0), file(NULL), fileName(NULL)
{ {
if(caseSensitivity == CASESENSETIVE){ switch (caseSensitivity)
cmp_func = strcmp; {
} else { case CASESENSITIVE:
cmp_func = strcasecmp; cmp_func = strcmp;
break;
case CASEINSENSETIVE:
cmp_func = strcasecmp;
break;
} }
mempool = new AsyncDNSMemPool(1024); mempool = new AsyncDNSMemPool(1024);
@ -67,195 +71,247 @@ DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity)
DOTCONFDocument::~DOTCONFDocument() DOTCONFDocument::~DOTCONFDocument()
{ {
for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i != nodeTree.end(); i++){ for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i)
delete(*i); delete(*i);
}
for(std::list<char*>::iterator i = requiredOptions.begin(); i != requiredOptions.end(); i++){ for (CharList::iterator i = requiredOptions.begin(); i != requiredOptions.end(); ++i)
free(*i); free(*i);
}
for(std::list<char*>::iterator i = processedFiles.begin(); i != processedFiles.end(); i++){ for (CharList::iterator i = processedFiles.begin(); i != processedFiles.end(); ++i)
free(*i); free(*i);
}
free(fileName); free(fileName);
delete mempool; delete mempool;
} }
int DOTCONFDocument::cleanupLine(char * line) int DOTCONFDocument::cleanupLine(char* line)
{ {
char * start = line; char* start = line;
char * bg = line; char* bg = line;
bool multiline = false; bool multiline = false;
bool concat = false; bool concat = false;
char * word = NULL; char* word = NULL;
if(!words.empty() && quoted) if (!words.empty() && quoted)
concat = true; concat = true;
while(*line){ while (*line)
if((*line == '#' || *line == ';') && !quoted){ {
if ((*line == '#' || *line == ';') && !quoted)
{
*bg = 0; *bg = 0;
if(strlen(start)){ if (strlen(start))
{
if(concat){ if (concat)
word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1); {
word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1);
strcpy(word, words.back()); strcpy(word, words.back());
strcat(word, start); strcat(word, start);
words.pop_back(); words.pop_back();
concat = false; concat = false;
} else {
word = mempool->strdup(start);
} }
else
word = mempool->Strdup(start);
words.push_back(word); words.push_back(word);
} }
break; break;
} }
if(*line == '=' && !quoted){
*line = ' ';continue; if (*line == '=' && !quoted)
{
*line = ' ';
continue;
} }
// Allowing \" in there causes problems with directory paths // Allowing \" in there causes problems with directory paths
// like "C:\MaNGOS\" // like "C:\MaNGOS\"
//if(*line == '\\' && (*(line+1) == '"' || *(line+1) == '\'')){ //if(*line == '\\' && (*(line+1) == '"' || *(line+1) == '\'')){
if(*line == '\\' && (*(line+1) == '\'')) { if (*line == '\\' && (*(line + 1) == '\''))
*bg++ = *(line+1); {
line+=2; continue; *bg++ = *(line + 1);
line += 2;
continue;
} }
if(*line == '\\' && *(line+1) == 'n'){
*bg++ = '\n';
line+=2; continue;
}
if(*line == '\\' && *(line+1) == 'r'){
*bg++ = '\r';
line+=2; continue;
}
if(*line == '\\' && (*(line+1) == '\n' || *(line+1) == '\r')){
*bg = 0;
if(strlen(start)){
if(concat){ if (*line == '\\' && *(line + 1) == 'n')
word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1); {
*bg++ = '\n';
line += 2;
continue;
}
if (*line == '\\' && *(line + 1) == 'r')
{
*bg++ = '\r';
line += 2;
continue;
}
if (*line == '\\' && (*(line + 1) == '\n' || *(line + 1) == '\r'))
{
*bg = 0;
if (strlen(start))
{
if (concat)
{
word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1);
strcpy(word, words.back()); strcpy(word, words.back());
strcat(word, start); strcat(word, start);
words.pop_back(); words.pop_back();
concat = false; concat = false;
} else {
word = mempool->strdup(start);
} }
else
word = mempool->Strdup(start);
words.push_back(word); words.push_back(word);
} }
multiline = true; multiline = true;
break; break;
} }
if(*line == '"' || *line == '\''){
quoted = !quoted;
++line; continue;
}
if(isspace((unsigned char)*line) && !quoted){
*bg++ = 0;
if(strlen(start)){
if(concat){ if (*line == '"' || *line == '\'')
word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1); {
quoted = !quoted;
++line;
continue;
}
if (isspace((unsigned char)*line) && !quoted)
{
*bg++ = 0;
if (strlen(start))
{
if (concat)
{
word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1);
strcpy(word, words.back()); strcpy(word, words.back());
strcat(word, start); strcat(word, start);
words.pop_back(); words.pop_back();
concat = false; concat = false;
} else {
word = mempool->strdup(start);
} }
else
word = mempool->Strdup(start);
words.push_back(word); words.push_back(word);
} }
start = bg; start = bg;
while(isspace((unsigned char)*++line)) {} while (isspace((unsigned char)*++line))
{
}
continue; continue;
} }
*bg++ = *line++; *bg++ = *line++;
} }
if(quoted && !multiline){ if (quoted && !multiline)
{
error(curLine, fileName, "unterminated quote"); error(curLine, fileName, "unterminated quote");
return -1; return -1;
} }
return multiline?1:0; return multiline ? 1 : 0;
} }
int DOTCONFDocument::parseLine() int DOTCONFDocument::parseLine()
{ {
char * word = NULL; char* word = NULL;
char * nodeName = NULL; char* nodeName = NULL;
char * nodeValue = NULL; char* nodeValue = NULL;
DOTCONFDocumentNode * tagNode = NULL; DOTCONFDocumentNode* tagNode = NULL;
bool newNode = false; bool newNode = false;
for(std::list<char*>::iterator i = words.begin(); i != words.end(); i++) { for (CharList::iterator i = words.begin(); i != words.end(); ++i)
{
word = *i; word = *i;
if(*word == '<'){ if (*word == '<')
newNode = true; newNode = true;
}
if(newNode){ if (newNode)
{
nodeValue = NULL; nodeValue = NULL;
nodeName = NULL; nodeName = NULL;
newNode = false; newNode = false;
} }
size_t wordLen = strlen(word); size_t wordLen = strlen(word);
if(word[wordLen-1] == '>'){ if (word[wordLen - 1] == '>')
word[wordLen-1] = 0; {
word[wordLen - 1] = 0;
newNode = true; newNode = true;
} }
if(nodeName == NULL){ if (nodeName == NULL)
{
nodeName = word; nodeName = word;
bool closed = true; bool closed = true;
if(*nodeName == '<'){ if (*nodeName == '<')
if(*(nodeName+1) != '/'){ {
if (*(nodeName + 1) != '/')
{
++nodeName; ++nodeName;
closed = false; closed = false;
} else { }
nodeName+=2; else
std::list<DOTCONFDocumentNode*>::reverse_iterator itr=nodeTree.rbegin(); {
for(; itr!=nodeTree.rend(); ++itr){ NodeList::reverse_iterator itr = nodeTree.rbegin();
if(!cmp_func(nodeName, (*itr)->name) && !(*itr)->closed){ nodeName += 2;
for (; itr != nodeTree.rend(); ++itr)
{
if (!cmp_func(nodeName, (*itr)->name) && !(*itr)->closed)
{
(*itr)->closed = true; (*itr)->closed = true;
curParent = (*itr)->parentNode; curParent = (*itr)->parentNode;
curPrev = *itr; curPrev = *itr;
break; break;
} }
} }
if(itr==nodeTree.rend()){
if(itr == nodeTree.rend())
{
error(curLine, fileName, "not matched closing tag </%s>", nodeName); error(curLine, fileName, "not matched closing tag </%s>", nodeName);
return -1; return -1;
} }
continue; continue;
} }
} }
tagNode = new DOTCONFDocumentNode; tagNode = new DOTCONFDocumentNode;
tagNode->name = strdup(nodeName); tagNode->name = strdup(nodeName);
tagNode->document = this; tagNode->document = this;
tagNode->fileName = processedFiles.back(); tagNode->fileName = processedFiles.back();
tagNode->lineNum = curLine; tagNode->lineNum = curLine;
tagNode->closed = closed; tagNode->closed = closed;
if(!nodeTree.empty()){
DOTCONFDocumentNode * prev = nodeTree.back();
if(prev->closed){
if(!nodeTree.empty())
{
DOTCONFDocumentNode* prev = nodeTree.back();
if (prev->closed)
{
curPrev->nextNode = tagNode; curPrev->nextNode = tagNode;
tagNode->previousNode = curPrev; tagNode->previousNode = curPrev;
tagNode->parentNode = curParent; tagNode->parentNode = curParent;
}
} else { else
{
prev->childNode = tagNode; prev->childNode = tagNode;
tagNode->parentNode = prev; tagNode->parentNode = prev;
curParent = prev; curParent = prev;
} }
} }
nodeTree.push_back(tagNode); nodeTree.push_back(tagNode);
curPrev = tagNode; curPrev = tagNode;
} else { }
else
{
nodeValue = word; nodeValue = word;
tagNode->pushValue(nodeValue); tagNode->pushValue(nodeValue);
} }
@ -263,7 +319,8 @@ int DOTCONFDocument::parseLine()
return 0; return 0;
} }
int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent)
int DOTCONFDocument::parseFile(DOTCONFDocumentNode* _parent)
{ {
char str[512]; char str[512];
int ret = 0; int ret = 0;
@ -273,27 +330,32 @@ int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent)
quoted = false; quoted = false;
size_t slen = 0; size_t slen = 0;
while(fgets(str, 511, file)){ while (fgets(str, 511, file))
{
++curLine; ++curLine;
slen = strlen(str); slen = strlen(str);
if( slen >= 510 ){ if (slen >= 510)
error(curLine, fileName, "warning: line too long"); error(curLine, fileName, "warning: line too long");
if (str[slen - 1] != '\n')
{
str[slen] = '\n';
str[slen + 1] = 0;
} }
if(str[slen-1] != '\n'){
str[slen] = '\n'; if ((ret = cleanupLine(str)) == -1)
str[slen+1] = 0;
}
if((ret = cleanupLine(str)) == -1){
break; break;
}
if(ret == 0){ if (ret == 0)
if(!words.empty()){ {
if (!words.empty())
{
ret = parseLine(); ret = parseLine();
mempool->free(); mempool->Free();
words.clear(); words.clear();
if(ret == -1){
if(ret == -1)
break; break;
}
} }
} }
} }
@ -301,46 +363,51 @@ int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent)
return ret; return ret;
} }
int DOTCONFDocument::checkConfig(const std::list<DOTCONFDocumentNode*>::iterator & from) int DOTCONFDocument::checkConfig(const NodeList::iterator& from)
{ {
int ret = 0; int ret = 0;
DOTCONFDocumentNode * tagNode = NULL; DOTCONFDocumentNode* tagNode = NULL;
int vi = 0; int vi = 0;
for(std::list<DOTCONFDocumentNode*>::iterator i = from; i != nodeTree.end(); i++){ for (NodeList::iterator i = from; i != nodeTree.end(); ++i)
{
tagNode = *i; tagNode = *i;
if(!tagNode->closed){ if (!tagNode->closed)
{
error(tagNode->lineNum, tagNode->fileName, "unclosed tag %s", tagNode->name); error(tagNode->lineNum, tagNode->fileName, "unclosed tag %s", tagNode->name);
ret = -1; ret = -1;
break; break;
} }
vi = 0;
while( vi < tagNode->valuesCount ){
if(strstr(tagNode->values[vi], "${") && strchr(tagNode->values[vi], '}') ){ vi = 0;
ret = macroSubstitute(tagNode, vi ); while (vi < tagNode->valuesCount)
mempool->free(); {
if(ret == -1){ if (strstr(tagNode->values[vi], "${") && strchr(tagNode->values[vi], '}'))
{
ret = macroSubstitute(tagNode, vi);
mempool->Free();
if (ret == -1)
break; break;
}
} }
++vi; ++vi;
} }
if(ret == -1){
if (ret == -1)
break; break;
}
} }
return ret; return ret;
} }
int DOTCONFDocument::setContent(const char * _fileName) int DOTCONFDocument::setContent(const char* _fileName)
{ {
int ret = 0; int ret = 0;
char realpathBuf[PATH_MAX]; char realpathBuf[PATH_MAX];
if(realpath(_fileName, realpathBuf) == NULL){ if (realpath(_fileName, realpathBuf) == NULL)
error(0, NULL, "realpath(%s) failed: %s", _fileName, strerror(errno)); {
error(0, NULL, "realpath (%s) failed: %s", _fileName, strerror(errno));
return -1; return -1;
} }
@ -348,79 +415,90 @@ int DOTCONFDocument::setContent(const char * _fileName)
processedFiles.push_back(strdup(realpathBuf)); processedFiles.push_back(strdup(realpathBuf));
if(( file = fopen(fileName, "r")) == NULL){ if ((file = fopen(fileName, "r")) == NULL)
{
error(0, NULL, "failed to open file '%s': %s", fileName, strerror(errno)); error(0, NULL, "failed to open file '%s': %s", fileName, strerror(errno));
return -1; return -1;
} }
// Try read utf8 header and skip it if exist // Try read utf8 header and skip it if exist
uint32 utf8header = 0; unsigned int utf8header = 0;
fgets((char*)&utf8header, 4, file); // Try read header fgets((char*)&utf8header, 4, file); // Try read header
if (utf8header!=0x00BFBBEF) // If not exist if (utf8header != 0x00BFBBEF) // If not exist
fseek(file, 0, SEEK_SET); // Reset read position fseek(file, 0, SEEK_SET); // Reset read position
ret = parseFile(); ret = parseFile();
(void) fclose(file); fclose(file);
if(!ret){ if (!ret)
{
if( (ret = checkConfig(nodeTree.begin())) == -1){ if ((ret = checkConfig(nodeTree.begin())) == -1)
return -1; return -1;
}
std::list<DOTCONFDocumentNode*>::iterator from; NodeList::iterator from;
DOTCONFDocumentNode * tagNode = NULL; DOTCONFDocumentNode* tagNode = NULL;
int vi = 0; int vi = 0;
for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){ for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i)
{
tagNode = *i; tagNode = *i;
if(!cmp_func("DOTCONFPPIncludeFile", tagNode->name)){ if (!cmp_func("DOTCONFPPIncludeFile", tagNode->name))
{
vi = 0; vi = 0;
while( vi < tagNode->valuesCount ){ while (vi < tagNode->valuesCount)
if(access(tagNode->values[vi], R_OK) == -1){ {
if (access(tagNode->values[vi], R_OK) == -1)
{
error(tagNode->lineNum, tagNode->fileName, "%s: %s", tagNode->values[vi], strerror(errno)); error(tagNode->lineNum, tagNode->fileName, "%s: %s", tagNode->values[vi], strerror(errno));
return -1; return -1;
} }
if(realpath(tagNode->values[vi], realpathBuf) == NULL){
error(tagNode->lineNum, tagNode->fileName, "realpath(%s) failed: %s", tagNode->values[vi], strerror(errno)); if (realpath(tagNode->values[vi], realpathBuf) == NULL)
{
error(tagNode->lineNum, tagNode->fileName, "realpath (%s) failed: %s", tagNode->values[vi], strerror(errno));
return -1; return -1;
} }
bool processed = false; bool processed = false;
for(std::list<char*>::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); itInode++){ for (CharList::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); ++itInode)
if(!strcmp(*itInode, realpathBuf)){ {
if (!strcmp(*itInode, realpathBuf))
{
processed = true; processed = true;
break; break;
} }
} }
if(processed){
if(processed)
break; break;
}
processedFiles.push_back(strdup(realpathBuf)); processedFiles.push_back(strdup(realpathBuf));
file = fopen(tagNode->values[vi], "r"); file = fopen(tagNode->values[vi], "r");
if(file == NULL){ if(file == NULL)
{
error(tagNode->lineNum, fileName, "failed to open file '%s': %s", tagNode->values[vi], strerror(errno)); error(tagNode->lineNum, fileName, "failed to open file '%s': %s", tagNode->values[vi], strerror(errno));
return -1; return -1;
} }
fileName = strdup(realpathBuf); fileName = strdup(realpathBuf);
from = nodeTree.end(); --from; from = nodeTree.end();
--from;
ret = parseFile(); ret = parseFile();
(void) fclose(file); fclose(file);
if(ret == -1)
if (ret == -1)
return -1; return -1;
if(checkConfig(++from) == -1){ if (checkConfig(++from) == -1)
return -1; return -1;
}
++vi; ++vi;
} }
} }
} }
if (!requiredOptions.empty())
if(!requiredOptions.empty())
ret = checkRequiredOptions(); ret = checkRequiredOptions();
} }
@ -429,124 +507,150 @@ int DOTCONFDocument::setContent(const char * _fileName)
int DOTCONFDocument::checkRequiredOptions() int DOTCONFDocument::checkRequiredOptions()
{ {
for(std::list<char*>::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ci++){ for (CharList::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ++ci)
{
bool matched = false; bool matched = false;
for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){ for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i)
if(!cmp_func((*i)->name, *ci)){ {
if (!cmp_func((*i)->name, *ci))
{
matched = true; matched = true;
break; break;
} }
} }
if(!matched){
if(!matched)
{
error(0, NULL, "required option '%s' not specified", *ci); error(0, NULL, "required option '%s' not specified", *ci);
return -1; return -1;
} }
} }
return 0; return 0;
} }
void DOTCONFDocument::error(int lineNum, const char * fileName_, const char * fmt, ...) void DOTCONFDocument::error(int lineNum, const char* fileName_, const char* fmt, ...)
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
size_t len = (lineNum!=0?strlen(fileName_):0) + strlen(fmt) + 50; size_t len = (lineNum != 0 ? strlen(fileName_) : 0) + strlen(fmt) + 50;
char * buf = (char*)mempool->alloc(len); char* buf = (char*)mempool->Alloc(len);
if(lineNum) if (lineNum)
(void) snprintf(buf, len, "DOTCONF++: file '%s', line %d: %s\n", fileName_, lineNum, fmt); snprintf(buf, len, "DOTCONF++: file '%s', line %d: %s\n", fileName_, lineNum, fmt);
else else
(void) snprintf(buf, len, "DOTCONF++: %s\n", fmt); snprintf(buf, len, "DOTCONF++: %s\n", fmt);
(void) vfprintf(stderr, buf, args); vfprintf(stderr, buf, args);
va_end(args); va_end(args);
} }
char * DOTCONFDocument::getSubstitution(char * macro, int lineNum) char* DOTCONFDocument::getSubstitution(char* macro, int lineNum)
{ {
char * buf = NULL; char* buf = NULL;
char * variable = macro+2; char* variable = macro + 2;
char * endBr = strchr(macro, '}'); char* endBr = strchr(macro, '}');
if(!endBr){ if (!endBr)
{
error(lineNum, fileName, "unterminated '{'"); error(lineNum, fileName, "unterminated '{'");
return NULL; return NULL;
} }
*endBr = 0; *endBr = 0;
char * defaultValue = strchr(variable, ':'); char* defaultValue = strchr(variable, ':');
if(defaultValue){ if (defaultValue)
{
*defaultValue++ = 0; *defaultValue++ = 0;
if(*defaultValue != '-'){ if (*defaultValue != '-')
{
error(lineNum, fileName, "incorrect macro substitution syntax"); error(lineNum, fileName, "incorrect macro substitution syntax");
return NULL; return NULL;
} }
++defaultValue;
if(*defaultValue == '"' || *defaultValue == '\''){
++defaultValue;
defaultValue[strlen(defaultValue)-1] = 0;
}
} else {
defaultValue = NULL;
}
char * subs = getenv(variable); ++defaultValue;
if( subs ){ if (*defaultValue == '"' || *defaultValue == '\'')
buf = mempool->strdup(subs); {
} else { ++defaultValue;
std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); defaultValue[strlen(defaultValue) - 1] = 0;
DOTCONFDocumentNode * tagNode = NULL; }
for(; i!=nodeTree.end(); i++){ }
else
defaultValue = NULL;
char* subs = getenv(variable);
if (subs)
buf = mempool->Strdup(subs);
else
{
NodeList::iterator i = nodeTree.begin();
DOTCONFDocumentNode* tagNode = NULL;
for (; i != nodeTree.end(); ++i)
{
tagNode = *i; tagNode = *i;
if(!cmp_func(tagNode->name, variable)){ if (!cmp_func(tagNode->name, variable))
if(tagNode->valuesCount != 0){ {
buf = mempool->strdup(tagNode->values[0]); if (tagNode->valuesCount != 0)
{
buf = mempool->Strdup(tagNode->values[0]);
break; break;
} }
} }
} }
if( i == nodeTree.end() ){
if( defaultValue ){ if (i == nodeTree.end())
buf = mempool->strdup(defaultValue); {
} else { if (defaultValue)
buf = mempool->Strdup(defaultValue);
else
{
error(lineNum, fileName, "substitution not found and default value not given"); error(lineNum, fileName, "substitution not found and default value not given");
return NULL; return NULL;
} }
} }
} }
return buf; return buf;
} }
int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex) int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode* tagNode, int valueIndex)
{ {
int ret = 0; int ret = 0;
char * macro = tagNode->values[valueIndex]; char* macro = tagNode->values[valueIndex];
size_t valueLen = strlen(tagNode->values[valueIndex])+1; size_t valueLen = strlen(tagNode->values[valueIndex]) + 1;
char * value = (char*)mempool->alloc(valueLen); char* value = (char*)mempool->Alloc(valueLen);
char * v = value; char* v = value;
char * subs = NULL; char* subs = NULL;
while(*macro){ while (*macro)
if(*macro == '$' && *(macro+1) == '{'){ {
char * m = strchr(macro, '}'); if (*macro == '$' && *(macro + 1) == '{')
{
char* m = strchr(macro, '}');
subs = getSubstitution(macro, tagNode->lineNum); subs = getSubstitution(macro, tagNode->lineNum);
if(subs == NULL){ if(subs == NULL)
{
ret = -1; ret = -1;
break; break;
} }
macro = m + 1; macro = m + 1;
*v = 0; *v = 0;
v = (char*)mempool->alloc(strlen(value)+strlen(subs)+valueLen); v = (char*)mempool->Alloc(strlen(value) + strlen(subs) + valueLen);
strcpy(v, value); strcpy(v, value);
value = strcat(v, subs); value = strcat(v, subs);
v = value + strlen(value); v = value + strlen(value);
continue; continue;
} }
*v++ = *macro++; *v++ = *macro++;
} }
*v = 0; *v = 0;
free(tagNode->values[valueIndex]); free(tagNode->values[valueIndex]);
@ -554,47 +658,47 @@ int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode * tagNode, int valueInd
return ret; return ret;
} }
const DOTCONFDocumentNode * DOTCONFDocument::getFirstNode() const const DOTCONFDocumentNode* DOTCONFDocument::getFirstNode() const
{ {
if ( !nodeTree.empty() ) { if (!nodeTree.empty())
return *nodeTree.begin(); return *nodeTree.begin();
} else { else
return NULL; return NULL;
}
} }
const DOTCONFDocumentNode * DOTCONFDocument::findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode, const DOTCONFDocumentNode * startNode) const const DOTCONFDocumentNode* DOTCONFDocument::findNode(const char* nodeName, const DOTCONFDocumentNode* parentNode, const DOTCONFDocumentNode* startNode) const
{ {
NodeList::const_iterator i = nodeTree.begin();
if (startNode == NULL)
std::list<DOTCONFDocumentNode*>::const_iterator i = nodeTree.begin();
if(startNode == NULL)
startNode = parentNode; startNode = parentNode;
if(startNode != NULL){ if (startNode != NULL)
while( i != nodeTree.end() && (*i) != startNode ){ {
while (i != nodeTree.end() && (*i) != startNode)
++i;
if (i != nodeTree.end())
++i; ++i;
}
if( i != nodeTree.end() ) ++i;
} }
for(; i!=nodeTree.end(); i++){ for (; i != nodeTree.end(); ++i)
{
if((*i)->parentNode != parentNode){ if ((*i)->parentNode != parentNode)
continue; continue;
}
if(!cmp_func(nodeName, (*i)->name)){ if (!cmp_func(nodeName, (*i)->name))
return *i; return *i;
}
} }
return NULL; return NULL;
} }
void DOTCONFDocument::setRequiredOptionNames(const char ** requiredOptionNames) void DOTCONFDocument::setRequiredOptionNames(const char** requiredOptionNames)
{ {
while(*requiredOptionNames){ while (*requiredOptionNames)
requiredOptions.push_back(strdup( *requiredOptionNames )); {
requiredOptions.push_back(strdup(*requiredOptionNames));
++requiredOptionNames; ++requiredOptionNames;
} }
} }

View file

@ -1,6 +1,3 @@
#ifndef DOTCONFPP_H #ifndef DOTCONFPP_H
#define DOTCONFPP_H #define DOTCONFPP_H
@ -21,77 +18,94 @@ class DOTCONFDocument;
class DOTCONFDocumentNode class DOTCONFDocumentNode
{ {
friend class DOTCONFDocument; friend class DOTCONFDocument;
private:
DOTCONFDocumentNode * previousNode;
DOTCONFDocumentNode * nextNode;
DOTCONFDocumentNode * parentNode;
DOTCONFDocumentNode * childNode;
char ** values;
int valuesCount;
char * name;
const DOTCONFDocument * document;
int lineNum;
char * fileName;
bool closed;
void pushValue(char * _value); private:
public: DOTCONFDocumentNode* previousNode;
DOTCONFDocumentNode(); DOTCONFDocumentNode* nextNode;
~DOTCONFDocumentNode(); DOTCONFDocumentNode* parentNode;
DOTCONFDocumentNode* childNode;
char** values;
int valuesCount;
char* name;
const DOTCONFDocument* document;
int lineNum;
char* fileName;
bool closed;
const char * getConfigurationFileName()const { return fileName; } void pushValue(char* _value);
int getConfigurationLineNumber() const { return lineNum; }
const DOTCONFDocumentNode * getNextNode() const { return nextNode; } public:
const DOTCONFDocumentNode * getPreviuosNode() const { return previousNode; }
const DOTCONFDocumentNode * getParentNode() const { return parentNode; } DOTCONFDocumentNode();
const DOTCONFDocumentNode * getChildNode() const { return childNode; } ~DOTCONFDocumentNode();
const char* getValue(int index = 0) const;
const char * getName() const { return name; } const char* getConfigurationFileName() const { return fileName; }
const DOTCONFDocument * getDocument() const { return document; } int getConfigurationLineNumber() const { return lineNum; }
const DOTCONFDocumentNode* getNextNode() const { return nextNode; }
const DOTCONFDocumentNode* getPreviuosNode() const { return previousNode; }
const DOTCONFDocumentNode* getParentNode() const { return parentNode; }
const DOTCONFDocumentNode* getChildNode() const { return childNode; }
const char* getValue(int index = 0) const;
const char* getName() const { return name; }
const DOTCONFDocument * getDocument() const { return document; }
}; };
class DOTCONFDocument class DOTCONFDocument
{ {
public: public:
enum CaseSensitive { CASESENSETIVE, CASEINSENSETIVE };
protected:
AsyncDNSMemPool * mempool;
private:
DOTCONFDocumentNode * curParent;
DOTCONFDocumentNode * curPrev;
int curLine;
bool quoted;
std::list<DOTCONFDocumentNode*> nodeTree;
std::list<char*> requiredOptions;
std::list<char*> processedFiles;
FILE * file;
char * fileName;
std::list<char*> words;
int (*cmp_func)(const char *, const char *);
int checkRequiredOptions(); enum CaseSensitive
int parseLine(); {
int parseFile(DOTCONFDocumentNode * _parent = NULL); CASESENSITIVE,
int checkConfig(const std::list<DOTCONFDocumentNode*>::iterator & from); CASEINSENSETIVE
int cleanupLine(char * line); };
char * getSubstitution(char * macro, int lineNum);
int macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex);
protected: protected:
virtual void error(int lineNum, const char * fileName, const char * fmt, ...) ATTR_PRINTF(4,5);
public: AsyncDNSMemPool* mempool;
DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSETIVE);
virtual ~DOTCONFDocument();
int setContent(const char * _fileName); private:
void setRequiredOptionNames(const char ** requiredOptionNames); typedef std::list<char*> CharList;
const DOTCONFDocumentNode * getFirstNode() const; typedef std::list<DOTCONFDocumentNode*> NodeList;
const DOTCONFDocumentNode * findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode = NULL, const DOTCONFDocumentNode * startNode = NULL) const;
DOTCONFDocumentNode* curParent;
DOTCONFDocumentNode* curPrev;
int curLine;
bool quoted;
NodeList nodeTree;
CharList requiredOptions;
CharList processedFiles;
FILE* file;
char* fileName;
CharList words;
int (*cmp_func)(const char*, const char*);
int checkRequiredOptions();
int parseLine();
int parseFile(DOTCONFDocumentNode* _parent = NULL);
int checkConfig(const NodeList::iterator& from);
int cleanupLine(char* line);
char* getSubstitution(char* macro, int lineNum);
int macroSubstitute(DOTCONFDocumentNode* tagNode, int valueIndex);
protected:
virtual void error(int lineNum, const char* fileName, const char* fmt, ...) ATTR_PRINTF(4,5);
public:
DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSITIVE);
virtual ~DOTCONFDocument();
int setContent(const char* _fileName);
void setRequiredOptionNames(const char** requiredOptionNames);
const DOTCONFDocumentNode * getFirstNode() const;
const DOTCONFDocumentNode * findNode(const char* nodeName, const DOTCONFDocumentNode* parentNode = NULL, const DOTCONFDocumentNode* startNode = NULL) const;
}; };
#endif #endif

View file

@ -1,12 +1,9 @@
#include "mempool.h" #include "mempool.h"
AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size): AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size)
pool(NULL), pos(0), size(_size) : pool(NULL), pos(0), size(_size)
{ {
pool = ::malloc(size); pool = malloc(size);
} }
AsyncDNSMemPool::PoolChunk::~PoolChunk() AsyncDNSMemPool::PoolChunk::~PoolChunk()
@ -14,87 +11,96 @@ AsyncDNSMemPool::PoolChunk::~PoolChunk()
::free(pool); ::free(pool);
} }
AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize): AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize)
chunks(NULL), chunksCount(0), defaultSize(_defaultSize), : chunks(NULL), chunksCount(0), defaultSize(_defaultSize),
poolUsage(0), poolUsageCounter(0) poolUsage(0), poolUsageCounter(0)
{ {
} }
AsyncDNSMemPool::~AsyncDNSMemPool() AsyncDNSMemPool::~AsyncDNSMemPool()
{ {
for(size_t i = 0; i<chunksCount; i++){ for (size_t i = 0; i < chunksCount; ++i)
delete chunks[i]; delete chunks[i];
}
::free(chunks); ::free(chunks);
} }
int AsyncDNSMemPool::initialize() bool AsyncDNSMemPool::initialize()
{ {
chunksCount = 1; chunksCount = 1;
chunks = (PoolChunk**)::malloc(sizeof(PoolChunk*)); chunks = (PoolChunk**)malloc(sizeof(PoolChunk*));
if(chunks == NULL) if (chunks == NULL)
return -1; return false;
chunks[chunksCount-1] = new PoolChunk(defaultSize); chunks[chunksCount - 1] = new PoolChunk(defaultSize);
return 0; return true;
} }
void AsyncDNSMemPool::addNewChunk(size_t size) void AsyncDNSMemPool::addNewChunk(size_t size)
{ {
++chunksCount; ++chunksCount;
chunks = (PoolChunk**)::realloc(chunks, chunksCount*sizeof(PoolChunk*));
if(size <= defaultSize) chunks = (PoolChunk**)realloc(chunks, chunksCount * sizeof(PoolChunk*));
chunks[chunksCount-1] = new PoolChunk(defaultSize); if (size <= defaultSize)
chunks[chunksCount - 1] = new PoolChunk(defaultSize);
else else
chunks[chunksCount-1] = new PoolChunk(size); chunks[chunksCount - 1] = new PoolChunk(size);
} }
void * AsyncDNSMemPool::alloc(size_t size) void* AsyncDNSMemPool::Alloc(size_t size)
{ {
PoolChunk * chunk = NULL; PoolChunk* chunk = NULL;
for(size_t i = 0; i<chunksCount; i++){ for (size_t i = 0; i < chunksCount; ++i)
{
chunk = chunks[i]; chunk = chunks[i];
if((chunk->size - chunk->pos) >= size){ if ((chunk->size - chunk->pos) >= size)
{
chunk->pos += size; chunk->pos += size;
return ((char*)chunk->pool) + chunk->pos - size; return ((char*)chunk->pool) + chunk->pos - size;
} }
} }
addNewChunk(size); addNewChunk(size);
chunks[chunksCount-1]->pos = size; chunks[chunksCount - 1]->pos = size;
return chunks[chunksCount-1]->pool; return chunks[chunksCount - 1]->pool;
} }
void AsyncDNSMemPool::free() void AsyncDNSMemPool::Free()
{ {
size_t pu = 0; size_t pu = 0;
size_t psz = 0; size_t psz = 0;
++poolUsageCounter; ++poolUsageCounter;
for(size_t i = 0; i<chunksCount; i++){ for (size_t i = 0; i < chunksCount; ++i)
{
pu += chunks[i]->pos; pu += chunks[i]->pos;
psz += chunks[i]->size; psz += chunks[i]->size;
chunks[i]->pos = 0; chunks[i]->pos = 0;
} }
poolUsage=(poolUsage>pu)?poolUsage:pu;
if(poolUsageCounter >= 10 && chunksCount > 1){ poolUsage = poolUsage > pu ? poolUsage : pu;
psz -= chunks[chunksCount-1]->size;
if(poolUsage < psz){ if (poolUsageCounter >= 10 && chunksCount > 1)
{
psz -= chunks[chunksCount - 1]->size;
if (poolUsage < psz)
{
--chunksCount; --chunksCount;
delete chunks[chunksCount]; delete chunks[chunksCount];
} }
poolUsage = 0; poolUsage = 0;
poolUsageCounter = 0; poolUsageCounter = 0;
} }
} }
void * AsyncDNSMemPool::calloc(size_t size) void* AsyncDNSMemPool::Calloc(size_t size)
{ {
return ::memset(this->alloc(size), 0, size); return ::memset(Alloc(size), 0, size);
} }
char * AsyncDNSMemPool::strdup(const char *str) char* AsyncDNSMemPool::Strdup(const char *str)
{ {
return ::strcpy((char*)this->alloc(strlen(str)+1), str); return ::strcpy((char*)Alloc(strlen(str) + 1), str);
} }

View file

@ -1,6 +1,3 @@
#ifndef ASYNC_DNS_MEMPOOL_H #ifndef ASYNC_DNS_MEMPOOL_H
#define ASYNC_DNS_MEMPOOL_H #define ASYNC_DNS_MEMPOOL_H
@ -8,39 +5,39 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#undef free
#undef calloc
#undef strdup
class AsyncDNSMemPool class AsyncDNSMemPool
{ {
private: private:
struct PoolChunk {
void * pool;
size_t pos;
size_t size;
PoolChunk(size_t _size); struct PoolChunk
~PoolChunk(); {
}; void* pool;
PoolChunk ** chunks; size_t pos;
size_t chunksCount; size_t size;
size_t defaultSize;
size_t poolUsage; PoolChunk(size_t _size);
size_t poolUsageCounter; ~PoolChunk();
};
void addNewChunk(size_t size); PoolChunk** chunks;
size_t chunksCount;
size_t defaultSize;
public: size_t poolUsage;
AsyncDNSMemPool(size_t _defaultSize = 4096); size_t poolUsageCounter;
virtual ~AsyncDNSMemPool();
int initialize(); void addNewChunk(size_t size);
void free();
void * alloc(size_t size); public:
void * calloc(size_t size);
char * strdup(const char *str); AsyncDNSMemPool(size_t _defaultSize = 4096);
virtual ~AsyncDNSMemPool();
bool initialize();
void Free();
void* Alloc(size_t size);
void* Calloc(size_t size);
char* Strdup(const char *str);
}; };
#endif #endif

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "8644" #define REVISION_NR "8645"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__