349 lines
9.2 KiB
C++
349 lines
9.2 KiB
C++
/*
|
||
* Configure.cpp
|
||
*
|
||
* Created on: 2011-11-16
|
||
*/
|
||
|
||
#include "Configure.h"
|
||
|
||
// #include "error.h"
|
||
#include "Utils.h"
|
||
#include <stdlib.h>
|
||
#include <fstream>
|
||
|
||
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<std::string, std::string>::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<std::string>& 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<std::string>((*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<std::string>((*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<int>(m_configureValue.size());
|
||
}
|
||
|
||
std::map<std::string, std::string> CConfigure::GetKeys() const
|
||
{
|
||
return m_configureValue;
|
||
}
|
||
|
||
}
|
||
}
|