235 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			235 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | /*
 | ||
|  |  * Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved. | ||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||
|  |  * you may not use this file except in compliance with the License. | ||
|  |  * You may obtain a copy of the License at | ||
|  |  * | ||
|  |  *     http://www.apache.org/licenses/LICENSE-2.0
 | ||
|  |  * | ||
|  |  * Unless required by applicable law or agreed to in writing, software | ||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, | ||
|  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
|  |  * See the License for the specific language governing permissions and | ||
|  |  * limitations under the License. | ||
|  |  */ | ||
|  | 
 | ||
|  | #include <sstream>
 | ||
|  | #include <functional>
 | ||
|  | #include "ConfigParser.h"
 | ||
|  | 
 | ||
|  | 
 | ||
|  | namespace { | ||
|  | const char COMMENT_CHARATER = '#'; | ||
|  | 
 | ||
|  | // Breaks the string at the separator (char) and returns a list of strings
 | ||
|  | void Split(const std::string &inString, std::vector<std::string> &outVector, const char delimiter) | ||
|  | { | ||
|  |     std::stringstream ss(inString); | ||
|  |     std::string item; | ||
|  |     while (std::getline(ss, item, delimiter)) { | ||
|  |         outVector.push_back(item); | ||
|  |     } | ||
|  | } | ||
|  | } | ||
|  | 
 | ||
|  | // Remove all spaces from the string
 | ||
|  | inline void ConfigParser::RemoveAllSpaces(std::string &str) const | ||
|  | { | ||
|  |     str.erase(std::remove_if(str.begin(), str.end(), isspace), str.end()); | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | // Remove spaces from both left and right based on the string
 | ||
|  | inline void ConfigParser::Trim(std::string &str) const | ||
|  | { | ||
|  |     str.erase(str.begin(), std::find_if(str.begin(), str.end(), std::not1(std::ptr_fun(::isspace)))); | ||
|  |     str.erase(std::find_if(str.rbegin(), str.rend(), std::not1(std::ptr_fun(::isspace))).base(), str.end()); | ||
|  |     return; | ||
|  | } | ||
|  | APP_ERROR ConfigParser::ParseConfig(const std::string &fileName) | ||
|  | { | ||
|  |     // Open the input file
 | ||
|  |     std::ifstream inFile(fileName); | ||
|  |     if (!inFile.is_open()) { | ||
|  |         std::cout << "cannot read setup.config file!" << std::endl; | ||
|  |         return APP_ERR_COMM_EXIST; | ||
|  |     } | ||
|  |     std::string line, newLine; | ||
|  |     int startPos, endPos, pos; | ||
|  |     // Cycle all the line
 | ||
|  |     while (getline(inFile, line)) { | ||
|  |         if (line.empty()) { | ||
|  |             continue; | ||
|  |         } | ||
|  |         startPos = 0; | ||
|  |         endPos = line.size() - 1; | ||
|  |         pos = line.find(COMMENT_CHARATER); // Find the position of comment
 | ||
|  |         if (pos != -1) { | ||
|  |             if (pos == 0) { | ||
|  |                 continue; | ||
|  |             } | ||
|  |             endPos = pos - 1; | ||
|  |         } | ||
|  |         newLine = line.substr(startPos, (endPos - startPos) + 1); // delete comment
 | ||
|  |         pos = newLine.find('='); | ||
|  |         if (pos == -1) { | ||
|  |             continue; | ||
|  |         } | ||
|  |         std::string na = newLine.substr(0, pos); | ||
|  |         Trim(na); // Delete the space of the key name
 | ||
|  |         std::string value = newLine.substr(pos + 1, endPos + 1 - (pos + 1)); | ||
|  |         Trim(value);                                   // Delete the space of value
 | ||
|  |         configData_.insert(std::make_pair(na, value)); // Insert the key-value pairs into configData_
 | ||
|  |     } | ||
|  |     return APP_ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | // Get the string value by key name
 | ||
|  | APP_ERROR ConfigParser::GetStringValue(const std::string &name, std::string &value) const | ||
|  | { | ||
|  |     if (configData_.count(name) == 0) { | ||
|  |         return APP_ERR_COMM_NO_EXIST; | ||
|  |     } | ||
|  |     value = configData_.find(name)->second; | ||
|  |     return APP_ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | // Get the int value by key name
 | ||
|  | APP_ERROR ConfigParser::GetIntValue(const std::string &name, int &value) const | ||
|  | { | ||
|  |     if (configData_.count(name) == 0) { | ||
|  |         return APP_ERR_COMM_NO_EXIST; | ||
|  |     } | ||
|  |     std::string str = configData_.find(name)->second; | ||
|  |     if (!(std::stringstream(str) >> value)) { | ||
|  |         return APP_ERR_COMM_INVALID_PARAM; | ||
|  |     } | ||
|  |     return APP_ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | // Get the unsigned integer value by key name
 | ||
|  | APP_ERROR ConfigParser::GetUnsignedIntValue(const std::string &name, unsigned int &value) const | ||
|  | { | ||
|  |     if (configData_.count(name) == 0) { | ||
|  |         return APP_ERR_COMM_NO_EXIST; | ||
|  |     } | ||
|  |     std::string str = configData_.find(name)->second; | ||
|  |     if (!(std::stringstream(str) >> value)) { | ||
|  |         return APP_ERR_COMM_INVALID_PARAM; | ||
|  |     } | ||
|  |     return APP_ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | // Get the bool value
 | ||
|  | APP_ERROR ConfigParser::GetBoolValue(const std::string &name, bool &value) const | ||
|  | { | ||
|  |     if (configData_.count(name) == 0) { | ||
|  |         return APP_ERR_COMM_NO_EXIST; | ||
|  |     } | ||
|  |     std::string str = configData_.find(name)->second; | ||
|  |     if (str == "true") { | ||
|  |         value = true; | ||
|  |     } else if (str == "false") { | ||
|  |         value = false; | ||
|  |     } else { | ||
|  |         return APP_ERR_COMM_INVALID_PARAM; | ||
|  |     } | ||
|  |     return APP_ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | // Get the float value
 | ||
|  | APP_ERROR ConfigParser::GetFloatValue(const std::string &name, float &value) const | ||
|  | { | ||
|  |     if (configData_.count(name) == 0) { | ||
|  |         return APP_ERR_COMM_NO_EXIST; | ||
|  |     } | ||
|  |     std::string str = configData_.find(name)->second; | ||
|  |     if (!(std::stringstream(str) >> value)) { | ||
|  |         return APP_ERR_COMM_INVALID_PARAM; | ||
|  |     } | ||
|  |     return APP_ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | // Get the double value
 | ||
|  | APP_ERROR ConfigParser::GetDoubleValue(const std::string &name, double &value) const | ||
|  | { | ||
|  |     if (configData_.count(name) == 0) { | ||
|  |         return APP_ERR_COMM_NO_EXIST; | ||
|  |     } | ||
|  |     std::string str = configData_.find(name)->second; | ||
|  |     if (!(std::stringstream(str) >> value)) { | ||
|  |         return APP_ERR_COMM_INVALID_PARAM; | ||
|  |     } | ||
|  |     return APP_ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | // Array like 1,2,4,8  split by ","
 | ||
|  | APP_ERROR ConfigParser::GetVectorUint32Value(const std::string &name, std::vector<uint32_t> &vector) const | ||
|  | { | ||
|  |     if (configData_.count(name) == 0) { | ||
|  |         return APP_ERR_COMM_NO_EXIST; | ||
|  |     } | ||
|  |     std::string str = configData_.find(name)->second; | ||
|  |     std::vector<std::string> splits; | ||
|  |     Split(str, splits, ','); | ||
|  |     uint32_t value = 0; | ||
|  |     std::stringstream ss; | ||
|  |     for (auto &it : splits) { | ||
|  |         if (!it.empty()) { | ||
|  |             std::stringstream ss(it); | ||
|  |             ss << it; | ||
|  |             ss >> value; | ||
|  |             vector.push_back(value); | ||
|  |         } | ||
|  |     } | ||
|  |     return APP_ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | // new config
 | ||
|  | void ConfigParser::NewConfig(const std::string &fileName) | ||
|  | { | ||
|  |     outfile_.open(fileName, std::ios::app); | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void ConfigParser::WriteString(const std::string &key, const std::string &value) | ||
|  | { | ||
|  |     outfile_ << key << " = " << value << std::endl; | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void ConfigParser::WriteInt(const std::string &key, const int &value) | ||
|  | { | ||
|  |     outfile_ << key << " = " << value << std::endl; | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void ConfigParser::WriteBool(const std::string &key, const bool &value) | ||
|  | { | ||
|  |     outfile_ << key << " = " << value << std::endl; | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void ConfigParser::WriteFloat(const std::string &key, const float &value) | ||
|  | { | ||
|  |     outfile_ << key << " = " << value << std::endl; | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void ConfigParser::WriteDouble(const std::string &key, const double &value) | ||
|  | { | ||
|  |     outfile_ << key << " = " << value << std::endl; | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void ConfigParser::WriteUint32(const std::string &key, const uint32_t &value) | ||
|  | { | ||
|  |     outfile_ << key << " = " << value << std::endl; | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void ConfigParser::SaveConfig() | ||
|  | { | ||
|  |     outfile_.close(); | ||
|  |     return; | ||
|  | } |