| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- #include "iniparser.h"
- #include "hdef.h"
- #include "herr.h"
- #include "hstring.h"
- #include "hfile.h"
- #include "hbase.h"
- #include <sstream>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- IniParser::IniParser() {
- _comment = DEFAULT_INI_COMMENT;
- _delim = DEFAULT_INI_DELIM;
- root_ = NULL;
- }
- IniParser::~IniParser() {
- Unload();
- }
- int IniParser::Unload() {
- SAFE_DELETE(root_);
- return 0;
- }
- int IniParser::LoadFromFile(const char* filepath) {
- _filepath = filepath;
- HFile file;
- if (file.open(filepath, "r") != 0) {
- return ERR_OPEN_FILE;
- }
- std::string str;
- file.readall(str);
- return LoadFromMem(str.c_str());
- }
- int IniParser::LoadFromMem(const char* data) {
- Unload();
- root_ = new IniNode;
- root_->type = IniNode::INI_NODE_TYPE_ROOT;
- std::stringstream ss;
- ss << data;
- std::string strLine;
- int line = 0;
- string::size_type pos;
- string content;
- string comment;
- string strDiv;
- IniNode* pScopeNode = root_;
- IniNode* pNewNode = NULL;
- while (std::getline(ss, strLine)) {
- ++line;
- content = trimL(strLine);
- if (content.length() == 0) {
- // blank line
- strDiv += '\n';
- continue;
- }
- // trim_comment
- comment = "";
- pos = content.find_first_of(_comment);
- if (pos != string::npos) {
- comment = content.substr(pos);
- content = content.substr(0, pos);
- }
- content = trimR(content);
- if (content.length() == 0) {
- strDiv += strLine;
- strDiv += '\n';
- continue;
- } else if (strDiv.length() != 0) {
- IniNode* pNode = new IniNode;
- pNode->type = IniNode::INI_NODE_TYPE_DIV;
- pNode->label = strDiv;
- pScopeNode->Add(pNode);
- strDiv = "";
- }
- if (content[0] == '[') {
- if (content[content.length()-1] == ']') {
- // section
- content = trim(content.substr(1, content.length()-2));
- pNewNode = new IniNode;
- pNewNode->type = IniNode::INI_NODE_TYPE_SECTION;
- pNewNode->label = content;
- root_->Add(pNewNode);
- pScopeNode = pNewNode;
- } else {
- // hlogw("format error, line:%d", line);
- continue; // ignore
- }
- } else {
- pos = content.find_first_of(_delim);
- if (pos != string::npos) {
- // key-value
- pNewNode = new IniNode;
- pNewNode->type = IniNode::INI_NODE_TYPE_KEY_VALUE;
- pNewNode->label = trim(content.substr(0, pos));
- pNewNode->value = trim(content.substr(pos+_delim.length()));
- pScopeNode->Add(pNewNode);
- } else {
- // hlogw("format error, line:%d", line);
- continue; // ignore
- }
- }
- if (comment.length() != 0) {
- // tail_comment
- IniNode* pNode = new IniNode;
- pNode->type = IniNode::INI_NODE_TYPE_SPAN;
- pNode->label = comment;
- pNewNode->Add(pNode);
- comment = "";
- }
- }
- // file end comment
- if (strDiv.length() != 0) {
- IniNode* pNode = new IniNode;
- pNode->type = IniNode::INI_NODE_TYPE_DIV;
- pNode->label = strDiv;
- root_->Add(pNode);
- }
- return 0;
- }
- void IniParser::DumpString(IniNode* pNode, string& str) {
- if (pNode == NULL) return;
- if (pNode->type != IniNode::INI_NODE_TYPE_SPAN) {
- if (str.length() > 0 && str[str.length()-1] != '\n') {
- str += '\n';
- }
- }
- switch (pNode->type) {
- case IniNode::INI_NODE_TYPE_SECTION: {
- str += '[';
- str += pNode->label;
- str += ']';
- }
- break;
- case IniNode::INI_NODE_TYPE_KEY_VALUE: {
- str += asprintf("%s %s %s", pNode->label.c_str(), _delim.c_str(), pNode->value.c_str());
- }
- break;
- case IniNode::INI_NODE_TYPE_DIV: {
- str += pNode->label;
- }
- break;
- case IniNode::INI_NODE_TYPE_SPAN: {
- str += '\t';
- str += pNode->label;
- }
- break;
- default:
- break;
- }
- for (auto p : pNode->children) {
- DumpString(p, str);
- }
- }
- string IniParser::DumpString() {
- string str;
- DumpString(root_, str);
- return str;
- }
- int IniParser::Save() {
- return SaveAs(_filepath.c_str());
- }
- int IniParser::SaveAs(const char* filepath) {
- string str = DumpString();
- if (str.length() == 0) {
- return 0;
- }
- HFile file;
- if (file.open(filepath, "w") != 0) {
- return ERR_SAVE_FILE;
- }
- file.write(str.c_str(), str.length());
- return 0;
- }
- string IniParser::GetValue(const string& key, const string& section) {
- if (root_ == NULL) return "";
- IniNode* pSection = root_;
- if (section.length() != 0) {
- pSection = root_->Get(section, IniNode::INI_NODE_TYPE_SECTION);
- if (pSection == NULL) return "";
- }
- IniNode* pKV = pSection->Get(key, IniNode::INI_NODE_TYPE_KEY_VALUE);
- if (pKV == NULL) return "";
- return pKV->value;
- }
- void IniParser::SetValue(const string& key, const string& value, const string& section) {
- if (root_ == NULL) {
- root_ = new IniNode;
- }
- IniNode* pSection = root_;
- if (section.length() != 0) {
- pSection = root_->Get(section, IniNode::INI_NODE_TYPE_SECTION);
- if (pSection == NULL) {
- pSection = new IniNode;
- pSection->type = IniNode::INI_NODE_TYPE_SECTION;
- pSection->label = section;
- root_->Add(pSection);
- }
- }
- IniNode* pKV = pSection->Get(key, IniNode::INI_NODE_TYPE_KEY_VALUE);
- if (pKV == NULL) {
- pKV = new IniNode;
- pKV->type = IniNode::INI_NODE_TYPE_KEY_VALUE;
- pKV->label = key;
- pSection->Add(pKV);
- }
- pKV->value = value;
- }
- template<>
- bool IniParser::Get(const string& key, const string& section, bool defvalue) {
- string str = GetValue(key, section);
- return str.empty() ? defvalue : getboolean(str.c_str());
- }
- template<>
- int IniParser::Get(const string& key, const string& section, int defvalue) {
- string str = GetValue(key, section);
- return str.empty() ? defvalue : atoi(str.c_str());
- }
- template<>
- float IniParser::Get(const string& key, const string& section, float defvalue) {
- string str = GetValue(key, section);
- return str.empty() ? defvalue : atof(str.c_str());
- }
- template<>
- void IniParser::Set(const string& key, const bool& value, const string& section) {
- SetValue(key, value ? "true" : "false", section);
- }
- template<>
- void IniParser::Set(const string& key, const int& value, const string& section) {
- SetValue(key, asprintf("%d", value), section);
- }
- template<>
- void IniParser::Set(const string& key, const float& value, const string& section) {
- SetValue(key, asprintf("%f", value), section);
- }
|