📄 warregistry.cpp
字号:
#include "StdAfx.h"#include "WarRegistry.h" // class implemented#if !defined(WAR_SYS_STAT_H_INCLUDED) && defined(HAVE_SYS_STAT_H)# define WAR_SYS_STAT_H_INCLUDED# include <sys/stat.h>#endif #if !defined(WAR_SYS_TYPES_H_INCLUDED) && defined(HAVE_SYS_TYPES_H)# define WAR_SYS_TYPES_H_INCLUDED# include <sys/types.h>#endif #ifndef WAR_LOG_H# include "WarLog.h"#endif/////////////////////////////// PUBLIC /////////////////////////////////////////============================= LIFECYCLE ====================================WarRegistry::WarRegistry() :mDoSave(false), mIsLoaded(false){}// WarRegistryWarRegistry::~WarRegistry(){ if (mDoSave) Save();}// ~WarRegistry//============================= OPERATORS ====================================//============================= OPERATIONS ===================================void WarRegistry::Open(war_ccstr_t filePath, bool doCreateIfNotExist) throw(WarException){ int mode = std::ios_base::in | std::ios_base::out; struct stat st; if (stat(filePath, &st) != 0) { if (!doCreateIfNotExist) WarThrow(WarError(WAR_ERR_OBJECT_NOT_FOUND), NULL); } mFile.open(filePath); if (!mFile.is_open()) WarThrow(WarError(WAR_ERR_NOT_OPEN), NULL); mFileName = filePath; Load(); if (mFile.is_open()) mFile.close();}war_registry_key_ptr_t WarRegistry::OpenKey(name_ccstr_t regPath, bool doCreateIfNotExist) throw(WarException){ war_registry_key_ptr_t key = mRootNodePtr;#ifdef UNICODE size_t len = wcslen(regPath);#else size_t len = strlen(regPath);#endif std::vector<war_sysch_t> buffer(len +1); memcpy(&buffer[0], regPath, len); if (key.IsEmpty()) WarThrow(WarError(WAR_ERR_INTERNAL_DATA_NOT_INITIALIZED), NULL); // Search down the tree war_sysch_t *p = &buffer[0]; const war_sysch_t *name = p; bool go_on = true; war_sysch_t ch = 1; for(;;) { while(*p && ('\\' != *p)) ++p; if ((ch = *p) == '\\') *p = 0; // Search for node :) key = key->Open(name); if (ch) name = ++p; else break; // exit from loop } return key;}void WarRegistry::Load() throw(WarException){ WarLog warning(WARLOG_WARNINGS, "WarRegistry::Load()"); WarLog err_log(WARLOG_ERROR, "WarRegistry::Load()"); if (mIsLoaded) WarThrow(WarError(WAR_ERR_ALREADY_INITIALIZED), NULL); mIsLoaded = true; mRootNodePtr = new WarRegistryKey(NULL, NULL); WarCollector<war_sysch_t> curr_name, curr_value, curr_comment; int current_line = 0; std::stack<WarRegistryKey::key_ptr_t> current_key; current_key.push(mRootNodePtr); while(!mFile.eof()) { char buf[1024 * 16]; ++current_line; mFile.getline(buf, sizeof(buf)); char *p = buf; char ch = 0; const char *name = NULL; while(p && isspace(*p)) ++p; if (0 == *p) curr_comment << '\n'; else if ('#' == *p) curr_comment << p << '\n'; else { // Is this a node? if ('<' == *p) { // Syntax: '<' ['/'] name '>' // Check if this is an endpoint bool is_endpoint = false; if (*++p == '/') { // Endpoint if (!*++p) goto syntax_error; is_endpoint = true; } name = p; while(*p && ('>' != *p)) ++p; if ('>' != *p) goto syntax_error; --p; while(isspace(*p)) --p; ++p; *p = 0; curr_name = name; if (is_endpoint) { // Endpoint. Verify and walk down the stack. if (curr_name.GetValue() != current_key.top()->GetName()) { err_log << "Name mismatch in node end-tag of \"" << curr_name << "\" in line " << current_line << " in configuration file \"" << mFileName << "\". Expected name \"" << current_key.top()->GetName() << "\". Bailing out." << war_endl; WarThrow(WarError(WAR_ERR_PARSER_ERROR), NULL); } current_key.pop(); if (current_key.empty()) { err_log << "Fatal mismatch in node end-tag of \"" << curr_name << "\" in line " << current_line << " in configuration file \"" << mFileName << "\". No parent node! Bailing out." << war_endl; WarThrow(WarError(WAR_ERR_NO_OBJECT), NULL); } } else { // Startpoint war_registry_key_ptr_t key_ptr = new WarRegistryKey( curr_name.GetValue().c_str(), curr_comment.GetValue().c_str()); if (current_key.top()->IsKey(curr_name.GetValue().c_str()) || current_key.top()->IsValue(curr_name.GetValue().c_str())) { err_log << "Duplicate node declaration of \"" << curr_name << "\" in line " << current_line << " in configuration file \"" << mFileName << "\". Bailing out." << war_endl; WarThrow(WarError(WAR_ERR_ALREADY_INITIALIZED), NULL); } current_key.top()->mChildren.insert(key_ptr); current_key.push(key_ptr); } } else { // Look for value // Syntax: [space*] name [space*] = [space*] value name = p; while(*p && (*p != '=')) ++p; if ('=' != *p) {syntax_error: warning << "Syntax error in line " << current_line << " in configuration file \"" << mFileName << "\". (ignoring)" << war_endl; goto prepare_for_next_item; } --p; while(isspace(*p)) --p; ++p; ch = *p; *p = 0; if (!*name) goto syntax_error; curr_name = name; *p = ch; while('=' != *p) ++p; assert('=' == *p); ++p; while(isspace(*p)) ++p; curr_value = p; war_registry_value_ptr_t val_ptr = new WarRegistryValue( curr_name.GetValue().c_str(), curr_comment.GetValue().c_str(), curr_value.GetValue().c_str()); if (current_key.top()->IsKey(curr_name.GetValue().c_str()) || current_key.top()->IsValue(curr_name.GetValue().c_str())) { err_log << "Duplicate value declaration of \"" << curr_name << "\" in line " << current_line << " in configuration file \"" << mFileName << "\". Bailing out." << war_endl; WarThrow(WarError(WAR_ERR_ALREADY_INITIALIZED), NULL); } current_key.top()->mValues.insert(val_ptr); }prepare_for_next_item: curr_comment = ""; curr_name = ""; curr_value = ""; } } mDoSave = true;}void WarRegistry::Save() throw(WarException){ if (mFile.is_open()) mFile.close(); mFile.open(mFileName.c_str(), std::ios_base::out | std::ios_base::trunc); SaveKey(0, mRootNodePtr);}//============================= CALLBACK ===================================//============================= ACCESS ===================================//============================= INQUIRY ===================================bool WarRegistry::IsKey(WarRegistryKey::name_ccstr_t name){ try { OpenKey(name); return true; } catch(WarException& ex) { if (ex.LocalError() != WAR_ERR_OBJECT_NOT_FOUND) throw(ex); } return false;}/////////////////////////////// PROTECTED ///////////////////////////////////void WarRegistry::SaveKey(int level, const war_registry_key_ptr_t& key)throw(WarException){ WarRegistryKey& my_key = *key; WarCollector<char> my_name, my_value, my_comment; bool have_name = false; std::string indent; if (!my_key.GetName().empty()) { my_name = my_key.GetName(); my_comment = my_key.GetComment(); have_name = true; indent = std::string(level * 4, ' '); mFile << my_comment.GetValue() << indent << '<' << my_name.GetValue() << '>' << '\n'; } // Write values { for(WarRegistryKey::value_set_t::const_iterator P = my_key.mValues.begin() ; P != my_key.mValues.end() ; ++P) { my_name = (*P)->GetName(); my_comment = (*P)->GetComment(); my_value = (*P)->GetValue(); mFile << my_comment.GetValue() << indent << my_name.GetValue() << " = " << my_value.GetValue() << '\n'; } } // Write subkeys { for(WarRegistryKey::key_set_t::const_iterator P = my_key.mChildren.begin() ; P != my_key.mChildren.end() ; ++P) { SaveKey(level + have_name ? 1 : 0, *P); } } if (have_name) mFile << indent << "</" << my_name.GetValue() << '>' << '\n';}/////////////////////////////// PRIVATE ///////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -