11 #include <drift/dslcore.h>
12 #include <drift/config.h>
13 #include <drift/config2.h>
14 #include <drift/GenLib.h>
22 ConfigSection::~ConfigSection() {
37 void ConfigSection::Clear() {
38 for (
auto& x : sections) {
42 for (
auto& x : values) {
48 ConfigSection * ConfigSection::GetSection(
const string& name) {
49 auto x = sections.find(name);
50 if (x != sections.end()) {
56 bool ConfigSection::HasValue(
const string& name)
const {
57 return (values.count(name) > 0);
71 const ConfigValue * ConfigSection::GetValue(
const string& name)
const {
72 auto x = values.find(name);
73 if (x != values.end()) {
79 bool ConfigSection::GetValue(
const string& name,
ConfigValue& value)
const {
80 auto x = values.find(name);
81 if (x != values.end()) {
88 void ConfigSection::SetValue(
const string& name,
const ConfigValue& val) {
89 auto x = values.find(name);
90 if (x != values.end()) {
97 bool ConfigValue::isBool(
const char * buf,
bool * val) {
98 if (buf == NULL || buf[0] == 0) {
return false; }
100 if (stricmp(buf,
"true") == 0 || stricmp(buf,
"on") == 0) {
101 if (val != NULL) { *val =
true; }
104 if (stricmp(buf,
"false") == 0 || stricmp(buf,
"off") == 0) {
105 if (val != NULL) { *val =
false; }
112 bool ConfigValue::isInt(
const char * buf) {
113 if (buf == NULL || buf[0] == 0) {
return false; }
115 int64 l = atoi64(buf);
116 if (l == 0 && strcmp(buf,
"0")) {
119 if (l == INT64_MAX && stricmp(buf,
"9223372036854775807")) {
122 if (l == INT64_MIN && stricmp(buf,
"-9223372036854775807") && stricmp(buf,
"-9223372036854775808")) {
127 for(
int i=0; buf[i] != 0; i++) {
128 if (buf[i] ==
'-' && i == 0 && buf[1] != 0) {
131 if(buf[i] < 48 || buf[i] > 57) {
139 bool ConfigValue::isFloat(
const char * buf) {
140 if (buf == NULL || buf[0] == 0) {
return false; }
142 double l = atof(buf);
143 if (l == 0.0 && strcmp(buf,
"0.0") && strcmp(buf,
"0.00")) {
146 if (l == HUGE_VAL || l == -HUGE_VAL) {
151 for(
int i=0; buf[i] != 0; i++) {
152 if (buf[i] ==
'-' && i == 0 && buf[1] != 0) {
159 if (periodCnt == 1) {
continue; }
162 if (buf[i] < 48 || buf[i] > 57) {
168 return (periodCnt == 1) ?
true:
false;
171 ConfigSection * ConfigSection::FindOrAddSection(
const string& name) {
183 bool ConfigSection::LoadFromString(
const string& config,
const string& fn) {
184 const char * p = config.c_str();
186 return loadFromString(&p, line, fn.c_str());
189 bool ConfigSection::loadFromString(
const char ** pconfig,
size_t& line,
const char * fn) {
190 bool long_comment =
false;
191 char buf[256] = { 0 };
193 const char * config = *pconfig;
194 while (*config != 0) {
195 const char * eol = strchr(config,
'\n');
197 size_t len = eol - config + 1;
202 config += strlen(config);
206 if (strlen(buf) < 2) {
212 while (strstr(buf,
" ")) {
219 if (!strcmp(buf,
"*/")) {
220 long_comment =
false;
225 if (!strncmp(buf,
"/*", 2)) {
230 if (stristr(buf,
"#include")) {
231 char * p = stristr(buf,
"#include");
235 char *q = strchr(p,
'\"');
240 const char * tmpc = data.c_str();
242 if (!loadFromString(&tmpc, tmpln, p)) {
243 printf(
"ERROR: Error loading #included file '%s'\n", p);
247 printf(
"ERROR: Error reading #included file '%s'\n", p);
251 printf(
"ERROR: Syntax is #include \"filename\"\n");
255 printf(
"ERROR: Syntax is #include \"filename\"\n");
261 if (buf[0] ==
'#' || !strncmp(buf,
"//", 2)) {
265 char *p = (
char *)&buf + (strlen(buf) - 2);
266 if (!strcmp(p,
" {")) {
268 auto sub = FindOrAddSection(buf);
269 if (!sub->loadFromString(&config, line, fn)) {
275 if (!strcmp(buf,
"};")) {
279 char * value = strchr(buf,
' ');
286 if (buf[0] && value[0]) {
287 auto x = values.find(buf);
288 if (x != values.end()) {
289 x->second->ParseString(value);
292 tmpv->ParseString(value);
298 printf(
"Unrecognized line at %s:%zu -> %s\n", fn, line, buf);
307 bool ConfigSection::LoadFromFile(FILE * fp,
const string& fn) {
308 if (fp == NULL) {
return false; }
312 if (len <= 0) {
return false; }
316 char * tmp = (
char *)dsl_malloc(len + 1);
317 if (fread(tmp, len, 1, fp) == 1) {
319 ret = LoadFromString(tmp, fn);
325 bool ConfigSection::LoadFromFile(
const string& filename) {
326 FILE * fp = fopen(filename.c_str(),
"rb");
327 if (fp == NULL) {
return false; }
328 bool ret = LoadFromFile(fp, filename);
333 void ConfigSection::writeSection(stringstream& sstr,
int level,
bool single)
const {
334 char * pref = (
char *)dsl_malloc(level+1);
335 for(
int i=0; i<level; i++) { pref[i] =
'\t'; }
338 sstr << pref << name <<
" {\n";
341 for (
auto& x : sections) {
342 x.second->writeSection(sstr, level + 1);
346 for (
auto& x : values) {
347 sstr <<
"\t" << pref << x.first <<
" " << x.second->AsString() <<
"\n";
350 sstr << pref <<
"};\n";
354 bool ConfigSection::WriteToFile(
const string& filename)
const {
355 FILE * fp = fopen(filename.c_str(),
"wb");
356 if (fp == NULL) {
return false; }
357 bool ret = WriteToFile(fp);
362 bool ConfigSection::WriteToFile(FILE * fp)
const {
363 if (!fp) {
return false; }
364 string str = WriteToString();
365 if (str.length() && fwrite(str.c_str(), str.length(), 1, fp) == 1) {
371 string ConfigSection::WriteToString()
const {
373 for (
auto& x : sections) {
374 x.second->writeSection(sstr, 0);
380 void ConfigSection::printSection(
size_t level)
const {
381 char * pref = (
char *)dsl_malloc(level + 2);
382 for (
int i = 0; i < level; i++) { pref[i] =
'\t'; }
385 printf(
"%sSection: %s\n", pref, name.c_str());
387 for (
auto& x : values) {
388 switch(x.second->Type) {
390 printf(
"%s[%s] = " I64FMT
"\n", pref, x.first.c_str(), x.second->Int);
393 printf(
"%s[%s] = %f\n", pref, x.first.c_str(), x.second->Float);
396 printf(
"%s[%s] = '%s'\n", pref, x.first.c_str(), x.second->sString.c_str());
399 printf(
"%s[%s] = Binary Data\n", pref, x.first.c_str());
402 printf(
"%s[%s] = %s\n", pref, x.first.c_str(), (x.second->Int > 0) ?
"true" :
"false");
405 printf(
"%s[%s] = Unknown Entry Type\n", pref, x.first.c_str());
412 for (
auto& x : sections) {
413 x.second->printSection(level+1);
417 void ConfigSection::PrintConfigTree()
const {
421 ConfigValue::ConfigValue() {
422 Type = DS_TYPE_UNKNOWN;
425 ConfigValue::~ConfigValue() {
429 bool ConfigValue::AsBool()
const {
431 if (Type == DS_TYPE_STRING) {
432 if (stricmp(sString.c_str(),
"true") == 0 || stricmp(sString.c_str(),
"on") == 0) {
435 }
else if (Type == DS_TYPE_FLOAT) {
436 return (Float >= 1.00);
437 }
else if (Type == DS_TYPE_INT || Type == DS_TYPE_BOOL) {
442 int64 ConfigValue::AsInt()
const {
443 if (Type == DS_TYPE_STRING || Type == DS_TYPE_BINARY) {
444 return atoi64(sString.c_str());
445 }
else if (Type == DS_TYPE_FLOAT) {
447 }
else if (Type == DS_TYPE_INT || Type == DS_TYPE_BOOL) {
452 double ConfigValue::AsFloat()
const {
453 if (Type == DS_TYPE_STRING || Type == DS_TYPE_BINARY) {
454 return atof(sString.c_str());
455 }
else if (Type == DS_TYPE_FLOAT) {
457 }
else if (Type == DS_TYPE_INT || Type == DS_TYPE_BOOL) {
462 string ConfigValue::AsString()
const {
463 if (Type == DS_TYPE_STRING || Type == DS_TYPE_BINARY) {
465 }
else if (Type == DS_TYPE_INT) {
467 }
else if (Type == DS_TYPE_FLOAT) {
469 }
else if (Type == DS_TYPE_BOOL) {
470 return (Int > 0) ?
"true" :
"false";
475 void ConfigValue::SetValue(
const ConfigValue& val) {
478 if (val.Type == DS_TYPE_STRING || val.Type == DS_TYPE_BINARY) {
479 sString = val.sString;
484 void ConfigValue::SetValue(int64 val) {
489 void ConfigValue::SetValue(
double val) {
491 Type = DS_TYPE_FLOAT;
494 void ConfigValue::SetValue(
const char * val) {
496 Type = DS_TYPE_STRING;
499 void ConfigValue::SetValue(
const string& val) {
501 Type = DS_TYPE_STRING;
504 void ConfigValue::SetValue(
const uint8_t * val,
size_t len) {
506 Type = DS_TYPE_BINARY;
507 sString.assign((
const char *)val, len);
509 void ConfigValue::SetValue(
bool val) {
515 void ConfigValue::ParseString(
const char * value) {
516 bool tmpbool =
false;
517 if (isFloat(value)) {
518 SetValue(atof(value));
519 }
else if (isBool(value, &tmpbool)) {
521 }
else if (isInt(value)) {
522 SetValue((int64)atoi64(value));
533 void ConfigValue::Reset() {
534 Type = DS_TYPE_UNKNOWN;
535 memset(&Int, 0,
sizeof(Int));
DSL_API_CLASS string mprintf(const string fmt,...)
DSL_API void DSL_CC dsl_free(void *ptr)
DSL_API size_t DSL_CC strlcpy(char *dst, const char *src, size_t siz)
DSL_API_CLASS int DSL_CC str_replaceA(char *Str, size_t BufSize, const char *FindStr, const char *ReplStr)
Simple string replacement.
DSL_API int64 DSL_CC ftell64(FILE *fp)
Cross-platform 64-bit ftell.
DSL_API int64 DSL_CC fseek64(FILE *fp, int64 offset, int whence)
Cross-platform 64-bit fseek.
DSL_API char *DSL_CC strtrim(char *buf, const char *trim="\r\n\t ", uint8 sides=TRIM_BOTH)
DSL_API_CLASS bool DSL_CC file_get_contents(const string &fn, vector< uint8 > &data, int64 maxSize=INT32_MAX)