#include "ini_file.h" #include #include #if defined(WIN32) || defined(_WIN64) #define bzero(b, s) memset(b, 0, s) #endif simple_ini::simple_ini() {} simple_ini::~simple_ini() {} std::string simple_ini::temporary_path(void) { #if defined(WIN32) || defined(_WIN64) char path[MAX_PATH] = { 0 }; if (GetTempPathA(_countof(path) - 1, path)) { if (path[lstrlenA(path) - 1] == '\\') path[lstrlenA(path) - 1] = 0; } return path; #else return "/tmp"; #endif } bool simple_ini::skip_empty(char*& ptr) { char* p = ptr; while(*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') ptr++; return ptr > p; } void simple_ini::trime(char*& ptr) { skip_empty(ptr); char* tail = ptr + strlen(ptr) - 1; while (tail >= ptr) { if (*tail != ' ' && *tail != '\t' && *tail != '\r' && *tail != '\n') break; tail--; } tail[1] = 0; } int simple_ini::load(const char* local_file) { int ret = 0; #if defined(WIN32) || defined(_WIN64) file_ = local_file; #else values_.clear(); FILE* src = fopen(local_file, "rb"); if (src) { char line[256]; char* oper = NULL; SECKEY sec; bzero(line, sizeof(line)); while (fgets(line, sizeof(line) - 1, src)) { oper = line; simple_ini::skip_empty(oper); if (strstr(oper, "//") == oper || strstr(oper, "#") == oper || *oper == 0) { bzero(line, sizeof(line)); continue; } if (*oper == '[') { oper++; if (strstr(oper, (char*)"]")) strstr(oper, (char*)"]")[0] = 0; if (sec.sec != oper) { if (sec.vals.size()) values_.push_back(sec); sec.vals.clear(); sec.sec = oper; std::vector::iterator it = std::find(values_.begin(), values_.end(), oper); if (it != values_.end()) { sec = *it; values_.erase(it); } } } else { char* v = strstr(oper, "="); if (v) { *v++ = 0; trime(oper); if (*oper) { trime(v); KEYVAL kv; kv.key = oper; kv.val = v; sec.vals.push_back(kv); std::sort(sec.vals.begin(), sec.vals.end()); } } } bzero(line, sizeof(line)); } fclose(src); if (sec.vals.size()) values_.push_back(sec); std::sort(values_.begin(), values_.end()); } else ret = errno; #endif return ret; } #if !defined(WIN32) && !defined(_WIN64) int simple_ini::save(const char* local_file) { FILE* dst = fopen(local_file, "wb"); if (dst) { for (size_t i = 0; i < values_.size(); ++i) { std::string val(values_[i].sec); val.insert(0, "["); val += "]\r\n"; fwrite(val.c_str(), 1, val.length(), dst); for (size_t j = 0; j < values_[i].vals.size(); ++j) { val = values_[i].vals[j].key + "=" + values_[i].vals[j].val + "\r\n"; fwrite(val.c_str(), 1, val.length(), dst); } val = "\r\n"; fwrite(val.c_str(), 1, val.length(), dst); } fclose(dst); } else return errno; } #endif std::string simple_ini::get(const char* sec, const char* key, const char* default_val) { #if defined(WIN32) || defined(_WIN64) char str[MAX_PATH] = { 0 }; GetPrivateProfileStringA(sec, key, default_val, str, _countof(str), file_.c_str()); return str; #else std::vector::iterator it = std::find(values_.begin(), values_.end(), sec); if (it == values_.end()) return default_val; std::vector::iterator it1 = std::find(it->vals.begin(), it->vals.end(), key); if (it1 == it->vals.end()) return default_val; else return it1->val; #endif } void simple_ini::set(const char* sec, const char* key, const char* val) { #if defined(WIN32) || defined(_WIN64) WritePrivateProfileStringA(sec, key, val, file_.c_str()); #else std::vector::iterator it = std::find(values_.begin(), values_.end(), sec); if (it == values_.end()) { KEYVAL kv; SECKEY sk; kv.key = key; kv.val = val; sk.sec = sec; sk.vals.push_back(kv); values_.push_back(sk); std::sort(values_.begin(), values_.end()); return; } std::vector::iterator it1 = std::find(it->vals.begin(), it->vals.end(), key); if (it1 == it->vals.end()) { KEYVAL kv; kv.key = key; kv.val = val; it->vals.push_back(kv); std::sort(it->vals.begin(), it->vals.end()); } else it1->val = val; #endif } void simple_ini::remove(const char* sec, const char* key) { #if defined(WIN32) || defined(_WIN64) #else std::vector::iterator it = std::find(values_.begin(), values_.end(), sec); if (it == values_.end()) return; std::vector::iterator it1 = std::find(it->vals.begin(), it->vals.end(), key); if (it1 != it->vals.end()) it->vals.erase(it1); #endif } void simple_ini::remove(const char* sec) { #if defined(WIN32) || defined(_WIN64) #else std::vector::iterator it = std::find(values_.begin(), values_.end(), sec); if (it != values_.end()) values_.erase(it); #endif } void simple_ini::clear(void) { values_.clear(); }