#include "Config.h" #include #include #include #include #include // use boost Config::Config() : m_keyDelimiter( CONFIG_DEFAULT_KEY_DELIMITER ) , m_valueDelimiter( CONFIG_DEFAULT_VALUE_DELIMITER ) { } /// @brief destructor Config::~Config() { Clear(); } /// @brief 지정된 Config 파일의 모든 정보를 읽어 내부 변수에 저장처리 /// @param path [in] Config file 의 전체 경로정보( C 배열 지원을 위해 & 사용안함) /// @return On success return true, otherwise return false bool Config::Open( const string path ) { ifstream file; // Config file open file.open( path.c_str()); if( file.is_open() == false ) { cerr << "[error] " << __FILE__<< ":" << __func__ << ": config file open failed.[" << path << "][" << strerror( errno ) << "]" << endl; return false; } // 기존 데이터가 존재하면 삭제 처리. if( m_configData.empty() == false ) m_configData.clear(); // config file parsing string line; string section; vector< string > configs; // 루프를 돌면서 Config 파일을 line 단위로 읽어들인당.... while( std::getline( file, line ) ) { // 앞뒤 공백 제거 처리 boost::trim( line ); // 공백 or 주석처리 라인 검사 if( line.empty() == true || boost::starts_with( line, string("#") ) == true || line == "\r" ) { continue; } // Section 여부 검사 if( boost::starts_with( line, string("[") ) == true && boost::ends_with( line, string("]") ) == true ) { // [] 로 정의된 section 의 문자열 값 추출 line.erase( line.begin() ); line.erase( line.end() -1 ); boost::trim( line ); if( section.empty() == false && section != line ) { // 이전 세션과 다른 신규 세션인 경우 // 기존까지 저장했던 데이터를 멤버 변수에 입력 처리 후 내부변수 초기화 처리. m_configData.insert( make_pair( section, configs ) ); section.clear(); configs.clear(); } // 신규 section 정보 저장처리. section = line; line.clear(); } else { // Section 정보가 아닌 경우 => 실제 설정값 .. ^^ configs.push_back( line ); } } // 마지막 세션 처리된 정보가 존재하는 경우 멤버 변수에 저장 처리. if( section.empty() == false ) { m_configData.insert( make_pair( section, configs ) ); } // 종료 처리. file.close(); return true; } /// @brief Config 멤버 변수에 저장된 데이터 삭제처리. /// @return void void Config::Clear() { m_configData.clear(); } /// @brief 해당 Section, Key 에 해당하는 value 값을 찾아 반환 /// @param section [in] 찾고자 하는 Section 값 /// @param key [in] 찾고자 하는 key 값 /// @param value [out] 해당 Section, Key 에 해당하는 value 값을 저장하기 위한 변수 /// @return On success return true, otherwise return false bool Config::GetConfig( const string section, const string key, string& value ) { // Section 에 대한 임시 데이터 저장객체 생성 vector< string > configs; // 해당 Section 이 존재하지 않는 경우 if( Find( section, configs ) == false ) return false; string line; string result; vector< string >::const_iterator it; // 해당 Key 이 존재하는지 검사 for( it = configs.begin(); it != configs.end(); it++) { line = *it; // Line 상의 주석 제거 string::size_type pos = line.find( '#' ); if( pos != string::npos) { line = line.substr(0, pos); boost::trim( line ); } // key = value 에서 key 부분 추출 pos = line.find( m_keyDelimiter ); if( pos == string::npos ) { continue; } else { result = line.substr(0, pos); boost::trim( result ); } if( key == result ) { // Key 값이 동일한 경우 value = line.substr( pos+1 ); boost::trim( value ); return true; } } return false; } /// @brief 해당 Section, Key 에 해당하는 value Array 값을 찾아 반환 /// @param section [in] 찾고자 하는 Section 값 /// @param key [in] 찾고자 하는 key 값 /// @param value [out] 해당 Section, Key 에 해당하는 value 값을 저장하기 위한 배열 /// @return On success return true, otherwise return false bool Config::GetConfig( const string section, const string key, vector< string >& value ) { string result; vector< string > vec; if( GetConfig( section, key, result ) == false ) return false; // 전달받은 result 값을 value delimiter 를 이용하여 parsing 처리 boost::split( vec, result, boost::is_any_of( m_valueDelimiter )); if( vec.empty() == true ) return false; // 루프를 돌면서 trim 처리 후 결과값 저장처리. vector< string >::const_iterator it; for( it = vec.begin(); it != vec.end(); it++) { result = boost::trim_copy( *it ); if( result.empty() == false ) value.push_back( result ); } if( value.empty() == true ) return false; else return true; } /// @brief Config 멤버 변수에 저장된 데이터 중 해당 Section 에 해당하는 데이터 반환. /// @param section [in] section 명 /// @param configData [out] 해당 Section 에서 읽은 Cofig 정보를 저장할 string 배열 /// @return On success return true, otherwise return false bool Config::Find( const string& section, vector& configData ) { map< string, vector< string > >::iterator it = m_configData.find( section ); if( it != m_configData.end() ) { // 해당 section 을 찾은 경우 configData = it->second; return true; } // 해당 section 을 찾지 못한 경우 return false; }