/* * Configure.cpp * * Created on: 2011-11-16 */ #include "Configure.h" // #include "error.h" #include "Utils.h" #include #include namespace pai { namespace conf { const std::string PAI_Conf = "pai.conf"; const int LINE_SIZE = 8192; CConfigure::CConfigure():recount(0),m_configureValue() { SetFromFile(GetConfigureFilePath(PAI_Conf)); } CConfigure::CConfigure(const std::string& configureFileName):recount(0),m_configureValue() { int i=configureFileName.find("/conf/"); std::string t=configureFileName; if(i!=std::string::npos) { t=configureFileName.c_str()+i+6; } SetFromFile(GetConfigureFilePath(t)); } CConfigure::CConfigure(const char* configureFileName):recount(0),m_configureValue() { if (configureFileName == NULL) { // throw pai::error::filesystem_error("Error constructor configure!"); } std::string t=configureFileName; if(strstr(configureFileName,"/conf/")) { t=strstr(configureFileName,"/conf/")+6; } const std::string filePath(t); SetFromFile(GetConfigureFilePath(filePath)); } CConfigure::CConfigure(const CConfigure & lrh):recount(0),m_configureValue() { recount = lrh.recount; m_configureValue = lrh.m_configureValue; } CConfigure & CConfigure::operator = (const CConfigure & lrh) { if (&lrh == this) return *this; recount = lrh.recount; m_configureValue = lrh.m_configureValue; return *this; } bool CConfigure::ExistFile(const char* path) { if (path == NULL) { return false; } if(access(path,0) == -1) { return false; } return true; } std::string CConfigure::GetConfigureFilePath(const std::string& configurePath) { if (configurePath.empty()) { // throw pai::error::filesystem_error("File name is empty!"); } std::string path; if ((configurePath[0] == '/')||(configurePath[1] == ':')) { path = GetPaiHomePath() +configurePath; } else { path = GetPaiHomePath() + "conf/" + configurePath; } if (!ExistFile(path.c_str())) { // throw pai::error::filesystem_error("File '" + configurePath + "' not found."); } return path; } CConfigure::~CConfigure() { } void CConfigure::SetFromFile(const std::string& path) { m_configureValue.clear(); pai::utils::File_ptr fp(path.c_str(), "r"); char line[LINE_SIZE]; while (fgets(line, LINE_SIZE, fp) != NULL) { SetFromLine(line); } replaceEnvromentValue(); } void CConfigure::SetFromLine(const char* configureLine) { std::string Line(configureLine); std::string key; std::string value; //去除每行前面的空白 size_t pos_line_front_space = Line.find_first_not_of(" \t"); if (pos_line_front_space != std::string::npos) { Line.erase(0, pos_line_front_space); } if (Line[0] == '#' || Line[0] == '[' || Line[0] == '\n' || Line[0] == '\r') { return; } //找到‘=’,‘=’前面的是key,后面的是value size_t pos_Equal = Line.find('='); if (pos_Equal != std::string::npos) { key = Line.substr(0, pos_Equal); key = ParseRawKey(key); value = Line.substr(pos_Equal + 1); value = ParseRawValue(value); if (key.empty() || value.empty()) { return; } m_configureValue.insert(std::map::value_type(key, value)); } } std::string CConfigure::GetValueByKey(const std::string& key) { return GetValueByKey(key.c_str()); } std::string CConfigure::GetValueByKey(const char* key) { std::string strRet = ""; map_type::const_iterator iter = m_configureValue.find(key); if (iter != m_configureValue.end()) { return (*iter).second; } else { return strRet; } } void CConfigure::GetKeys(std::vector& key) const { map_type::const_iterator iter = m_configureValue.begin(); while (iter != m_configureValue.end()) { key.push_back((*iter).first); iter++; } } void CConfigure::Print() { map_type::const_iterator iter = m_configureValue.begin(); while (iter != m_configureValue.end()) { std::cout << (*iter).first << "=" << (*iter).second << std::endl; iter++; } } std::string CConfigure::GetPaiHomePath() { std::string totalPath = pai::utils::CUtils::GetPaiHome(); m_configureValue.clear(); if (totalPath[totalPath.size() - 1] != '/') { totalPath += "/"; } return totalPath; } std::string CConfigure::ParseRawKey(std::string& rawKey) { size_t pos_key_space = rawKey.find_last_not_of(" \t"); if (pos_key_space != std::string::npos) { rawKey.erase(pos_key_space + 1); } return rawKey; } std::string CConfigure::ParseRawValue(std::string& rawValue) { //去掉value前面‘=’后面的空白 size_t pos_value_front_space = rawValue.find_first_not_of(" \t"); if (pos_value_front_space != std::string::npos) { rawValue.erase(0, pos_value_front_space); } //去掉value后的注释 size_t pos_Pant = rawValue.find('#'); if (pos_Pant != std::string::npos) { rawValue.erase(pos_Pant); } //去掉value后的换行符 size_t pos_value_end_newLine = rawValue.find('\n'); if (pos_value_end_newLine != std::string::npos) { rawValue.erase(pos_value_end_newLine); } //去掉value后的空白 size_t pos_value_end_space = rawValue.find_last_not_of(" \t"); if (pos_value_end_space != std::string::npos) { rawValue.erase(pos_value_end_space + 1); } return rawValue; } void CConfigure::replaceEnvromentValue() { for (map_type::iterator it = m_configureValue.begin(); it != m_configureValue.end(); it++) { std::string value = static_cast((*it).second); recount = 0; (*it).second = replaceWord(value, false); } for (map_type::iterator it = m_configureValue.begin(); it != m_configureValue.end(); it++) { std::string value = static_cast((*it).second); recount = 0; (*it).second = replaceWord(value, true); } } std::string CConfigure::replaceWord(std::string& value, bool usingEnv) { std::string result = ""; for (size_t i = 0; i < value.length(); i++) { char c = value[i]; //check escape char if (c == '\\') { if (i <= (value.length() - 2) && value[i + 1] == '$') { if (usingEnv) { result.push_back('$'); } else { result.push_back('\\'); result.push_back('$'); } i++; continue; } } if (c == '$' && i != (value.length() - 1)) { std::string paramName = ""; size_t j; bool brace_l = false; bool brace_equential = false; for (j = i + 1; j < value.length(); j++) { if (value[j] == '{') { brace_l = true; continue; } else if (value[j] == '}') { if (brace_l) { brace_equential = true; } break; } else { paramName.push_back(value[j]); } } if (!brace_equential) { continue; } if (!paramName.empty()) { if (usingEnv) { result.append(replaceWithEnvValue(paramName)); } else { std::string newValue = ""; if (recount <= 20) { std::vector < std::string > keys; GetKeys( keys); for (size_t s = 0; s < keys.size(); s++) { size_t pos_k = value.find(keys[s]); if (pos_k != std::string::npos) { if ((pos_k > 0 && value[pos_k - 1] != '\\') || pos_k == 0) { //cout << recount << ":" << ":" << pos_k << ":" << paramName << ":" << keys[i] << endl; recount++; std::string tempValue = GetValueByKey( paramName); newValue = replaceWord(tempValue, false); } } } } if (newValue.empty()) { newValue = "${" + paramName + "}"; } result.append(newValue); } } i = j; } else { result.push_back(c); } } return result; } std::string CConfigure::replaceWithEnvValue(const std::string& key) { std::string value = ""; char* envValue = getenv(key.c_str()); if (envValue != NULL) { value = std::string(envValue); } return value; } int CConfigure::GetMapSize() { return static_cast(m_configureValue.size()); } std::map CConfigure::GetKeys() const { return m_configureValue; } } }