记录参数修改的功能,主要分为五部分,包括:1、维护一个参数配置文件的map,用来保存参数表中的参数值,与参数配置文件中的内容保持一致;2、维护一个记录参数修改内容的multimap,详细记录下参数的修改信息,包括修改时间、从什么值修改成什么值、谁做的修改、修改的哪个配置文件中的参数等;3、维护一个统计参数修改的map,只记录参数最早的修改时间和参数修改次数统计;4、参数敏感词过滤功能,是为了过滤掉那些不可记录的内容,比如,密码、密文参数等;5、对该功能进行简单的封装,让接口更简洁;还有就是其他的功能;
主要分为五个部分,每个部分用一个类实现:
1,对该记录功能进行的封装:SettingModifyRecordKeeping类
SettingModifyRecordKeeping.h代码如下:
#ifndef __SETTING_MODIFY_RECORD_KEEPING_H__
#define __SETTING_MODIFY_RECORD_KEEPING_H__
#ifdef __cplusplus
#include <string>
#include <vector>
#include <map>
#include "KeepingModifyUtilitys.h"
#include "MappingSettingConfigFile.h"
#include "MappingSettingModifyRecord.h"
#define COUNT_OF_PARAM_IN_MODIFY_FILE_MAX 10
#define PARAM_CHANGE_RECORD_KEEPING_FILE "./config_param_modify.record"
#define SYSTEM_OPTIONS_FILE "./yx_config_system.ini"
#define CUSTOM_OPTIONS_FILE "./yx_config_customer.ini"
#define MONITOR_OPTIONS_FILE "./yx_config_tr069.ini"
#define VERSION_OPTIONS_FILE "./yx_config_version.ini"
class SettingModifyRecordKeeping {
public:
SettingModifyRecordKeeping(std::string fileName);
~SettingModifyRecordKeeping() {}
int load(void);
int save(void);
int reSet(void);
int set(const char* name, const char* value, int module, const char* fileTag);
void setModifyTimeStamp(); //设置 m_paramItem 的modifyTimeStamp
void setModifySourceModule(int module); //设置 m_paramItem 的sourceModule
void setModifiedFile(const char* fileTag); //设置 m_paramItem 的modifiedFile
void setParamOldValue(); //设置 m_paramItem 的oldValue, 从 m_paramConfigFileMap 中获取
void initialParamItem(const char* name, const char* value, int module, const char* fileTag);
private:
ParametersItem m_paramItem;
MappingSettingModifyRecord* m_paramModifyRecordMapping;
MappingSettingConfigFile* m_paramConfigFileMapping;
std::string m_fileName;
};
#endif // __cplusplus
#endif //__SETTING_MODIFY_RECORD_KEEPING_H__
SettingModifyRecordKeeping.cpp代码如下:
#include <iostream>
#include <algorithm>
#include <fstream>
#include <sstream>
#include "Log/LogC.h"
#include "logSettings.h"
#include "ThreadMutex.h"
#include "SettingModifyRecordKeeping.h"
using namespace std;
int gModifyRecordResetFlag = 0;
SettingModifyRecordKeeping::SettingModifyRecordKeeping(std::string fileName)
{
//create ParamStatisticsMapping MappingSettingConfigFile MappingSettingModifyRecord
m_paramConfigFileMapping = new MappingSettingConfigFile();
(*m_paramConfigFileMapping).addConfigFile(SYSTEM_OPTIONS_FILE);
(*m_paramConfigFileMapping).addConfigFile(CUSTOM_OPTIONS_FILE);
(*m_paramConfigFileMapping).addConfigFile(MONITOR_OPTIONS_FILE);
(*m_paramConfigFileMapping).addConfigFile(VERSION_OPTIONS_FILE);
//initial m_paramModifyRecordMapping
m_paramModifyRecordMapping = new MappingSettingModifyRecord(fileName);
}
/**
* @Func: load
* ps. :initial ParamStatisticsMapping MappingSettingConfigFile MappingSettingModifyRecord
* @Param:
* @Return: int
*
**/
int SettingModifyRecordKeeping::load(void)
{
(*m_paramConfigFileMapping).loadConfigFileParam();
(*m_paramModifyRecordMapping).loadModifyRecordParam();
settingsLogVerbose("Has loading OK.\n");
//(*m_paramModifyRecordMapping).paramModifyRecordMapOutput();
return 0;
}
/**
* @Func: save
* @Param:
* @Return: int
*
* e.g: <2012-Jan-01 08:02:05.521>
**/
int SettingModifyRecordKeeping::save(void)
{
if(gModifyRecordResetFlag == 1){
settingsLogVerbose("save, gModifyRecordResetFlag = 1.\n");
return 0;
}
// sync m_paramConfigFileMapping && save m_paramModifyRecordMapping to file
(*m_paramConfigFileMapping).updateConfigFileParamMap(m_paramItem.paramName, m_paramItem.newValue);
(*m_paramModifyRecordMapping).formatingParamItemOutput();
settingsLogVerbose("Has saved OK.\n");
return 0;
}
/**
* @Func: reSet
* @Param:
* @Return: int
*
* e.g: <2012-Jan-01 08:02:05.521>
**/
int SettingModifyRecordKeeping::reSet(void)
{
//delete file
fstream fstr(PARAM_CHANGE_RECORD_KEEPING_FILE, ios::out | ios::binary);
fstr << endl;
fstr.close();
(*m_paramModifyRecordMapping).resetModifyRecordOutput();
gModifyRecordResetFlag = 1;
settingsLogVerbose("Has reSetting OK.\n");
return 0;
}
/**
* @Func: set
* @Param: name, type:: const char *
* value, type:: const char *
* module, type:: int
* fileTag, type:: const char *
* @Return: int
*
**/
int SettingModifyRecordKeeping::set(const char* name, const char* value, int module, const char* fileTag)
{
initialParamItem(name, value, module, fileTag);
//save to m_paramModifyRecordMapping && dereplication
(*m_paramModifyRecordMapping).updateModifyRecordParamMap(&m_paramItem);
(*m_paramModifyRecordMapping).dereplicationModifyRecordParamMap();
//sync m_paramConfigFileMapping
(*m_paramConfigFileMapping).updateConfigFileParamMap(m_paramItem.paramName, m_paramItem.newValue);
settingsLogVerbose("Has set item[%s] value[%s] OK.\n", name, value);
return 0;
}
/**
* @Func: setModifyTimeStamp
* @Param:
* @Return: void
*
**/
void SettingModifyRecordKeeping::setModifyTimeStamp()
{
char buf[64] = {0};
DateTimeStamp sDTime;
struct timespec sTimeSpec;
getDateTimeStamp(&sDTime);
clock_gettime(CLOCK_MONOTONIC, &sTimeSpec);
snprintf(buf, 64 - 1, "%04d-%s-%02d %02d:%02d:%02d.%03d",
sDTime.mYear, gMonthStr[sDTime.mMonth].c_str(), sDTime.mDay,
sDTime.mHour, sDTime.mMinute, sDTime.mSecond, sTimeSpec.tv_nsec / 1000000);
m_paramItem.modifyTimeStamp = buf;
settingsLogVerbose("SET: modifyTimeStamp[%s] OK.\n", (m_paramItem.modifyTimeStamp).c_str());
return ;
}
/**
* @Func: setModifySourceModule
* @Param: module, type:: int
* @Return: void
*
**/
void SettingModifyRecordKeeping::setModifySourceModule(int module)
{
std::string value("");
switch(module) {
case RecordChangedSource_STBMonitor:
m_paramItem.sourceModule = "STBManageTool";
break;
case RecordChangedSource_tr069Manager:
m_paramItem.sourceModule = "TR069";
break;
case RecordChangedSource_JsLocalSetting:
m_paramItem.sourceModule = "JSLocal";
break;
case RecordChangedSource_JsEpgSetting:
m_paramItem.sourceModule = "JSEPG";
break;
case RecordChangedSource_Other:
m_paramItem.sourceModule = "Other";
break;
default:
m_paramItem.sourceModule = "";
break;
}
settingsLogVerbose("SET: sourceModule[%s] OK.\n", (m_paramItem.sourceModule).c_str());
return ;
}
/**
* @Func: setModifiedFile
* @Param: fileTag, type:: const char *
* @Return: void
*
**/
void SettingModifyRecordKeeping::setModifiedFile(const char* fileTag)
{
std::string fTag(fileTag);
if(fTag.compare("system") == 0){
m_paramItem.modifiedFile = SYSTEM_OPTIONS_FILE;
} else if(fTag.compare("customer") == 0){
m_paramItem.modifiedFile = CUSTOM_OPTIONS_FILE;
} else if(fTag.compare("tr069") == 0){
m_paramItem.modifiedFile = MONITOR_OPTIONS_FILE;
} else if(fTag.compare("version") == 0){
m_paramItem.modifiedFile = VERSION_OPTIONS_FILE;
} else {
m_paramItem.modifiedFile = "";
}
settingsLogVerbose("SET: modifiedFile[%s].\n", (m_paramItem.modifiedFile).c_str());
return ;
}
/**
* @Func: setParamOldValue
* @Param:
* @Return: void
*
**/
void SettingModifyRecordKeeping::setParamOldValue()
{
if(m_paramItem.paramName.empty()){
settingsLogError("setParamOldValue m_paramItem.paramName[%s]ERROR.\n", m_paramItem.paramName.c_str());
return;
}
m_paramItem.oldValue = (*m_paramConfigFileMapping).getConfigFileParamValue(m_paramItem.paramName);
settingsLogVerbose("SET: oldvalue[%s] OK.\n", m_paramItem.oldValue.c_str());
return ;
}
/**
* @Func: initialParamItem
* @Param: name, type:: const char *
* value, type:: const char *
* module, type:: int
* fileTag, type:: const char *
* @Return: void
*
**/
void SettingModifyRecordKeeping::initialParamItem(const char* name, const char* value, int module, const char* fileTag)
{
m_paramItem.paramName = name;
m_paramItem.newValue = value;
setParamOldValue();
setModifyTimeStamp();
setModifySourceModule(module);
setModifiedFile(fileTag);
settingsLogVerbose("initialParamItem m_paramItem.paramName[%s] newValue[%s] sourceModule[%s] oldValue[%s] modifyTimeStamp[%s] modifiedFile[%s].\n",
m_paramItem.paramName.c_str(), m_paramItem.newValue.c_str(), (m_paramItem.sourceModule).c_str(),
m_paramItem.oldValue.c_str(), m_paramItem.modifyTimeStamp.c_str(), m_paramItem.modifiedFile.c_str());
return ;
}
加载默认配置参数功能:MappingSettingConfigFile类实现
MappingSettingConfigFile.h源码如下:
#ifndef __MAPPING_SETTING_CONFIG_FILE_H__
#define __MAPPING_SETTING_CONFIG_FILE_H__
#ifdef __cplusplus
#include <string>
#include <vector>
#include <map>
#define PARAM_CHANGE_RECORD_KEEPING_FILE_PATH "./config_param_modify.record"
class MappingSettingConfigFile { /* 在内存中维护对配置文件中参数的键值对的拷贝 */
public:
MappingSettingConfigFile(){}
~MappingSettingConfigFile(){}
bool addConfigFile(std::string file);
bool deleteConfigFile(std::string file);
int loadConfigFileParam(); //将 m_cfgFileList 中配置文件里的键值对加载到 m_paramConfigFileMap
int unloadConfigFileParam();
int updateConfigFileParamMap(std::string& name, std::string& value); //在每次将修改信息写入到 m_fileName 文件后,更新内存中的配置文件拷贝 m_paramConfigFileMap ,
std::string getConfigFileParamValue(std::string name);
int paramConfigFileMapOutput();
private:
std::map<std::string, std::string> m_paramConfigFileMap; //保存各个配置文件(包括:yx_config_system.ini,yx_config_customer.ini,yx_config_tr069.ini)中的键值对
std::vector<std::string> m_cfgFileList; //可能会修改的配置文件列表,在构造时初始化
};
#endif // __cplusplus
#endif //__MAPPING_SETTING_CONFIG_FILE_H__
MappingSettingConfigFile.cpp源码:
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include "Log/LogC.h"
#include "logSettings.h"
#include "ThreadMutex.h"
#include "MappingSettingConfigFile.h"
#include "SensitiveParamFiltering.h"
using namespace std;
/**
* @Func: addConfigFile
* @Param: file, type:: std::string
* @Return: bool
*
**/
bool MappingSettingConfigFile::addConfigFile(std::string file)
{
if(file.empty()){
settingsLogError("file[%s] cannot empty, ERROR.\n", file.c_str());
return false;
}
m_cfgFileList.push_back(file);
return true;
}
/**
* @Func: deleteConfigFile
* @Param: file, type:: std::string&
* @Return: bool
*
**/
bool MappingSettingConfigFile::deleteConfigFile(std::string file)
{
if(file.empty()){
settingsLogError("file[%s] cannot empty, ERROR.\n", file.c_str());
return false;
}
m_cfgFileList.erase(std::find(m_cfgFileList.begin(), m_cfgFileList.end(), file));
return true;
}
/**
* @Func: loadConfigFileParam
* ps. : 从 m_cfgFileList 文件列表中包含的文件里加载到 m_paramConfigFileMap
* @Param:
* @Return: int
*
**/
int MappingSettingConfigFile::loadConfigFileParam()
{
FILE *fp = NULL;
char ch;
std::string line("");
std::string tag("");
std::string value("");
std::vector<std::string>::iterator cfgFileListIt;
std::string::size_type position;
for (cfgFileListIt = m_cfgFileList.begin(); cfgFileListIt != m_cfgFileList.end(); ++cfgFileListIt){
settingsLogVerbose("I will load \"%s\".\n", (*cfgFileListIt).c_str());
fp = fopen((*cfgFileListIt).c_str(), "rb");
if (!fp) {
settingsLogError("Open file error!\n");
return -1;
}
while((ch = fgetc(fp)) != (char)EOF || !line.empty()) {
if(ch != '\n' && ch != (char)EOF) {
line += ch;
continue;
}
position = line.find('=');
if (position == std::string::npos) {
settingsLogWarning("Not found \"=\", line=[%s]\n", line.c_str());
line.clear();
continue;
}
tag = line.substr(0, position);
value = line.substr(position + 1);
updateConfigFileParamMap(tag, value);
line.clear();
}
fclose(fp);
fp = NULL;
settingsLogVerbose("load \"%s\" ok.\n", (*cfgFileListIt).c_str());
}
settingsLogVerbose("Has load ConfigFile OK.\n");
return 0;
}
/**
* @Func: updateConfigFileParamMap
* ps. : 将解析到的 添加到 m_paramConfigFileMap
* @Param: name, type:: std::string&
* value, type:: std::string&
* @Return: int
*
**/
int MappingSettingConfigFile::updateConfigFileParamMap(std::string& name, std::string& value)
{
if(name.empty()){
settingsLogError("name[%s] is NULL.\n", name.c_str());
return -1;
}
std::map<std::string, std::string>::iterator cfgFileMapIt = m_paramConfigFileMap.find(name);
settingsLogVerbose("INPUT: name[%s] value[%s].\n", name.c_str(), value.c_str());
if (gSensitiveParamFilter.filteringSensitiveParam(name)) {
if (cfgFileMapIt != m_paramConfigFileMap.end())
cfgFileMapIt->second = "";
else
m_paramConfigFileMap[name] = "";
} else {
if (cfgFileMapIt != m_paramConfigFileMap.end())
cfgFileMapIt->second = value;
else
m_paramConfigFileMap[name] = value;
}
settingsLogVerbose("Has update OK.\n");
return 0;
}
/**
* @Func: unloadConfigFileParam
* @Param:
* @Return: int
*
**/
int MappingSettingConfigFile::unloadConfigFileParam()
{
if(m_paramConfigFileMap.empty()) {
settingsLogError("unloadConfigFileParam:: m_paramConfigFileMap has been empty.\n");
return -1;
}
m_paramConfigFileMap.erase(m_paramConfigFileMap.begin(), m_paramConfigFileMap.end()); //成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合
settingsLogVerbose("Has unload ConfigFile OK.\n");
return 0;
}
/**
* @Func: getConfigFileParamValue
* ps. :从 m_paramConfigFileMap 获取参数的旧值
* @Param: name, type:: std::string&
* @Return: std::string
*
**/
std::string MappingSettingConfigFile::getConfigFileParamValue(std::string name)
{
std::map<std::string, std::string>::iterator cfgFileMapIt;
std::string value("");
cfgFileMapIt = m_paramConfigFileMap.find(name);
if (cfgFileMapIt != m_paramConfigFileMap.end())
value = cfgFileMapIt->second;
settingsLogVerbose("GET: name[%s] value[%s].\n", name.c_str(), value.c_str());
return value;
}
/**
* @Func: paramConfigFileMapOutput
* @Param:
* @Return: int
*
**/
int MappingSettingConfigFile::paramConfigFileMapOutput()
{
std::map<std::string, std::string>::iterator cfgFileMapIt;
for(cfgFileMapIt = m_paramConfigFileMap.begin();cfgFileMapIt != m_paramConfigFileMap.end(); ++cfgFileMapIt){
cout << "paramConfigFileMapOutput:: key: "<< cfgFileMapIt->first << " value: " << cfgFileMapIt->second <<endl;
}
return 0;
}
2,将记录的参数修改进行保存的功能:MappingSettingModifyRecord类
MappingSettingModifyRecord.h如下:
#ifndef __MAPPING_SETTING_MODIFY_RECORD_H__
#define __MAPPING_SETTING_MODIFY_RECORD_H__
#ifdef __cplusplus
#include <string>
#include <map>
#include "ThreadMutex.h"
#include "KeepingModifyUtilitys.h"
#include "MappingSettingStatistics.h"
class MappingSettingModifyRecord { /* 在内存中维护对记录修改的文件中参数的拷贝 */
public:
MappingSettingModifyRecord(std::string fileName);
~MappingSettingModifyRecord(){}
int loadModifyRecordParam(); //将文件 m_fileName 中的修改信息加载到 m_paramModifyRecordMap
int unloadModifyRecordParam();
int updateModifyRecordParamMap(ParametersItem *paramItem); //在每次将修改信息写入到 m_fileName 文件后,更新内存中的文件拷贝 m_paramModifyRecordMap ,
int dereplicationModifyRecordParamMap();
int getModifyRecordEarliestTimeStamp(std::string& name, std::string& timeStamp);
int deleteModifyRecordByTimeStamp(std::string& name, std::string& timeStamp);
int formatingParamItemOutput();
int resetModifyRecordOutput();
int paramModifyRecordMapOutput();
private:
std::string m_fileName; //用来保存参数记录的文件名称,即 PARAM_CHANGE_RECORD_KEEPING_FILE_PATH
std::multimap<std::string, ParametersItem> m_paramModifyRecordMap;
MappingSettingStatistics* m_paramStatisticsMapping;
std::string m_version;
ThreadMutex_Type m_mutex;
};
#endif // __cplusplus
#endif //__MAPPING_SETTING_MODIFY_RECORD_H__
MappingSettingModifyRecord.cpp源码如下:
#include <iostream>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include "Log/LogC.h"
#include "logSettings.h"
#include "ThreadMutex.h"
#include "MappingSettingModifyRecord.h"
#include "SensitiveParamFiltering.h"
using namespace std;
int IsModifyRecordMappingLoaded = 0;
MappingSettingModifyRecord::MappingSettingModifyRecord(std::string fileName)
: m_fileName(fileName)
, m_version(PARAM_CHANGE_RECORD_KEEPING_VERSION)
{
if (m_mutex) {
settingsLogWarning("thread mutex has init.\n");
}
m_mutex = ThreadMutexCreate( );
//paramStatisticsMapping initial
m_paramStatisticsMapping = new MappingSettingStatistics(fileName);
}
/**
* @Func: loadModifyRecordParam
* ps. :逐行从文件 config_param_modify.record 加载到 m_paramModifyRecordMap
* @Param:
* @Return: int
*
**/
int MappingSettingModifyRecord::loadModifyRecordParam()
{
(*m_paramStatisticsMapping).loadStatisticsRecord();
(*m_paramStatisticsMapping).statisticsRecordMapOutput();
FILE *fp = NULL;
bool fileAvailableLineFlag = false;
std::string line("");
settingsLogVerbose("loadModifyRecordParam.\n");
std::ifstream fin(m_fileName.c_str(), std::ios::in);
while(std::getline(fin, line)) {
if (!fileAvailableLineFlag) { //清除第一行
std::string::size_type position = line.find('=');
if (position != std::string::npos) {
std::string tag = line.substr(0, position);
std::string value = line.substr(position + 1);
if ((tag.compare("CFversion") == 0) && (value.compare(m_version) == 0)) {
fileAvailableLineFlag = true;
line.clear();
settingsLogVerbose("File is Available.\n");
continue;
}
}
settingsLogWarning("The available information is not found.(%s)\n", line.c_str());
break;
}
settingsLogVerbose("Start parse line[%s].\n", line.c_str());
updateModifyRecordParamMap(parseRecordLine(line)); //逐行添加
line.clear();
}
settingsLogVerbose("Load %s ok.\n", m_fileName.c_str());
IsModifyRecordMappingLoaded = 1;
dereplicationModifyRecordParamMap();
return 0;
}
/**
* @Func: updateModifyRecordParamMap
* ps. :将解析到的 添加到 m_paramModifyRecordMap
* @Param: paramItem, type:: ParametersItem *
* @Return: int
*
**/
int MappingSettingModifyRecord::updateModifyRecordParamMap(ParametersItem *paramItem)
{
if( (paramItem->paramName).compare(ERROR_PARAM_ITEM.paramName) == 0
|| (paramItem->paramName).empty() || (paramItem->modifyTimeStamp).empty()){
settingsLogError("paramItem[%p], paramName[%s] modifyTimeStamp[%s].\n", paramItem, paramItem->paramName.c_str(), paramItem->modifyTimeStamp.c_str());
return -1;
}
//if has loaded then: sync m_paramStatisticsMapping
if(IsModifyRecordMappingLoaded == 1){
(*m_paramStatisticsMapping).updateStatisticsRecord(paramItem);
}
pair<std::string, ParametersItem> modifyRecord(paramItem->paramName, *paramItem);
m_paramModifyRecordMap.insert(modifyRecord);
/* settingsLogVerbose( "updateModifyRecordParamMap paramItem.paramName[%s] newValue[%s] sourceModule[%s] oldValue[%s] modifyTimeStamp[%s] modifiedFile[%s].\n",
(paramItem->paramName).c_str(), (paramItem->newValue).c_str(), (paramItem->sourceModule).c_str(),
(paramItem->oldValue).c_str(), (paramItem->modifyTimeStamp).c_str(), (paramItem->modifiedFile).c_str()
);
*/
return 0;
}
/**
* @Func: dereplicationModifyRecordParamMap
* ps. :去除多余的时间戳最早的条目,去除重复
* @Param:
* @Return: int
*
**/
int MappingSettingModifyRecord::dereplicationModifyRecordParamMap()
{
int count = 0, i = 0;
int tmpSize = 0, deleteSize = 0;
std::string timeStamp("");
std::map<std::string, ParamStatistics>::iterator paramStatisticIt;
std::map<std::string, ParamStatistics> paramStatisticsMap = (*m_paramStatisticsMapping).getStatisticsRecordMap();
/**
* 判断 m_paramStatisticsMapping 中的个数:
* if 大于 COUNT_OF_PARAM_IN_MODIFY_FILE_MAX 个:
* 获取 m_paramStatisticsMapping 中的时间戳;
* 查找时间戳 m_paramModifyRecordMap对应的条目,删除条目;
* 计数器 -1;
* 更新获取最早的时间戳;
* 否则,直接添加;
**/
for(paramStatisticIt = paramStatisticsMap.begin(); paramStatisticIt != paramStatisticsMap.end(); ++paramStatisticIt){
while( (*m_paramStatisticsMapping).getStatisticsRecordCount((paramStatisticIt->second).paramName) > COUNT_OF_PARAM_IN_MODIFY_FILE_MAX ){
tmpSize = m_paramModifyRecordMap.size();
//删除最早时间戳的条目
timeStamp = (*m_paramStatisticsMapping).getStatisticsRecordTimeStamps((paramStatisticIt->second).paramName);
deleteModifyRecordByTimeStamp((paramStatisticIt->second).paramName, timeStamp);
//更新计数器
deleteSize = tmpSize - m_paramModifyRecordMap.size();
settingsLogVerbose("name[%s] has been deleted item count[%d] .\n", (paramStatisticIt->second).paramName.c_str(), tmpSize, deleteSize);
(*m_paramStatisticsMapping).modifyStatisticsRecordCount((paramStatisticIt->second).paramName, STATISTAC_RECORD_COUNT_FLAG_MINUS, deleteSize);
//更新最早时间戳
getModifyRecordEarliestTimeStamp((paramStatisticIt->second).paramName, timeStamp);
(*m_paramStatisticsMapping).modifyStatisticsRecordTimeStamps((paramStatisticIt->second).paramName, timeStamp);
}
settingsLogVerbose("name[%s] earliestTimeStamp[%s] recordCount[%d].\n", (paramStatisticIt->second).paramName.c_str(), (paramStatisticIt->second).earliestTimeStamp.c_str(), (paramStatisticIt->second).recordCount);
}
return 0;
}
/**
* @Func: unloadModifyRecordParam
* @Param:
* @Return: int
*
**/
int MappingSettingModifyRecord::unloadModifyRecordParam()
{
if(m_paramModifyRecordMap.empty()){
settingsLogError("unloadModifyRecordParam:: m_paramModifyRecordMap has been empty, ERROR.\n");
return -1;
}
m_paramModifyRecordMap.erase(m_paramModifyRecordMap.begin(), m_paramModifyRecordMap.end());
settingsLogVerbose("Has unload ModifyRecord OK.\n");
return 0;
}
/**
* @Func: getModifyRecordEarliestTimeStamp
* @Param: name, type:: std::string&
* timeStamp, type:: std::string&
* @Return: int
*
**/
int MappingSettingModifyRecord::getModifyRecordEarliestTimeStamp(std::string& name, std::string& timeStamp)
{
if(name.empty()){
settingsLogError(" paramName[%s].\n",name.c_str());
return -1;
}
std::multimap<std::string, ParametersItem>::iterator it = m_paramModifyRecordMap.find(name);
if(it == m_paramModifyRecordMap.end()){
settingsLogVerbose("Cannot find ModifyRecordParam[%s] .\n", name.c_str());
return -1;
}
timeStamp = (it->second).modifyTimeStamp;
it = m_paramModifyRecordMap.lower_bound(name);
while(it != m_paramModifyRecordMap.upper_bound(name)) {
settingsLogVerbose("modifyTimeStamp[%s], TimeStamp[%s]\n", (it->second).modifyTimeStamp.c_str(), timeStamp.c_str());
if(dateTimeCompare(timeStamp, (it->second).modifyTimeStamp) > 0){
timeStamp = (it->second).modifyTimeStamp;
}
++it;
}
settingsLogVerbose("GET: name[%s] earliestTimeStamp[%s].\n", name.c_str(), timeStamp.c_str());
return 0;
}
/**
* @Func: formatingParamItemOutput
* @Param:
* @Return: int
*
* e.g: Parameter[ Device.Username ] @<2012-Jan-01 08:02:05.521> modified by[ JS ]from[ testcpe ]to[ testcpe55 ]into file[ /root/yx_config_tr069.ini ].
**/
int MappingSettingModifyRecord::formatingParamItemOutput()
{
FILE *fp = NULL;
std::string line("");
std::multimap<std::string, ParametersItem>::iterator it;
if (ThreadMutexLock(m_mutex))
settingsLogWarning("thread mutex locking error.\n");
if ((fp = fopen(m_fileName.c_str(), "wb")) == NULL) {
settingsLogError("Open file error.(%s)\n", m_fileName.c_str());
return -1;
}
line = "CFversion=" + m_version + "\n";
fwrite(line.c_str(), 1, line.length(), fp);
for (it = m_paramModifyRecordMap.begin(); it != m_paramModifyRecordMap.end(); ++it) {
line = "Parameter[ " + it->first;
line += " ] @<" + (it->second).modifyTimeStamp;
line += "> modified by[ " + (it->second).sourceModule;
if (gSensitiveParamFilter.filteringSensitiveParam(it->first))
line += " ]from[ *** ]to[ ***";
else {
line += " ]from[ " + (it->second).oldValue;
line += " ]to[ " + (it->second).newValue;
}
line += " ]into file[ " + (it->second).modifiedFile;
line += " ].\n";
fwrite(line.c_str(), 1, line.length(), fp);
}
fclose(fp);
if (ThreadMutexUnLock(m_mutex))
settingsLogWarning("thread mutex locking error.\n");
settingsLogVerbose("Format Output to [%s] ok.\n", m_fileName.c_str());
//(*m_paramStatisticsMapping).statisticsRecordMapOutput(); //for test
return 0;
}
/**
* @Func: resetModifyRecordOutput
* @Param:
* @Return: int
*
**/
int MappingSettingModifyRecord::resetModifyRecordOutput()
{
FILE *fp = NULL;
std::string line("");
if (ThreadMutexLock(m_mutex))
settingsLogWarning("thread mutex locking error.\n");
if ((fp = fopen(m_fileName.c_str(), "wb")) == NULL) {
settingsLogError("Open file error.(%s)\n", m_fileName.c_str());
return -1;
}
line = "CFversion=" + m_version + "\n";
fwrite(line.c_str(), 1, line.length(), fp);
fclose(fp);
if (ThreadMutexUnLock(m_mutex))
settingsLogWarning("thread mutex locking error.\n");
settingsLogVerbose("Reset [%s] ok.\n", m_fileName.c_str());
return 0;
}
/**
* @Func: deleteModifyRecordByTimeStamp
* @Param: name, type:: std::string&
* timeStamp, type:: std::string&
* @Return: int
*
**/
int MappingSettingModifyRecord::deleteModifyRecordByTimeStamp(std::string& name, std::string& timeStamp)
{
std::multimap<std::string, ParametersItem>::iterator it = m_paramModifyRecordMap.find(name);
settingsLogVerbose("RecordParam[%s] modifyTimeStamp[%s] .\n", name.c_str(), timeStamp.c_str());
if(it == m_paramModifyRecordMap.end()){
settingsLogError("Cannot find ModifyRecordParam[%s] modifyTimeStamp[%s] .\n", name.c_str(), timeStamp.c_str());
return -1;
}
#if 0
//delete method 1
it = m_paramModifyRecordMap.lower_bound(name);
while(it != m_paramModifyRecordMap.upper_bound(name)) {
settingsLogVerbose("earliestTimeStamp[%s].\n", (it->second).modifyTimeStamp.c_str());
if(dateTimeCompare((it->second).modifyTimeStamp, timeStamp) == 0){
m_paramModifyRecordMap.erase(it);
}
++it;
}
#else
//delete method 2
pair<std::multimap<std::string, ParametersItem>::iterator, std::multimap<std::string, ParametersItem>::iterator> position;
position = m_paramModifyRecordMap.equal_range(name);
/**
* 如果键存在,函数返回2个指针,第一个指针指向键第一个匹配的元素
* 第二个指针指向键最后一个匹配的元素的下一位置
**/
while (position.first != position.second){
settingsLogVerbose(" earliestTimeStamp[%s]\n", (position.first->second).modifyTimeStamp.c_str());
if(dateTimeCompare(((position.first)->second).modifyTimeStamp, timeStamp) == 0){
m_paramModifyRecordMap.erase(position.first);
}
position.first++;
}
#endif
settingsLogVerbose("Has delete OK.\n");
//paramModifyRecordMapOutput(); //for test
return 0;
}
/**
* @Func: paramModifyRecordMapOutput
* @Param:
* @Return: int
*
**/
int MappingSettingModifyRecord::paramModifyRecordMapOutput()
{
std::multimap<std::string, ParametersItem>::iterator it;
for(it = m_paramModifyRecordMap.begin(); it != m_paramModifyRecordMap.end(); ++it)
cout << "paramModifyRecordMapOutput:: key:"<< it->first << " paramName:" << (it->second).paramName << " newValue:" << (it->second).newValue << " sourceModule: " << (it->second).sourceModule << " oldValue:" << (it->second).oldValue << " modifyTimeStamp:" << (it->second).modifyTimeStamp << " modifiedFile:" << (it->second).modifiedFile <<endl;
return 0;
}
3,记录参数修改的次数和记录下最早的修改时间的功能:MappingSettingStatistics类
MappingSettingStatistics.h如下:
#ifndef __MAPPING_SETTING_STATISTICS_H__
#define __MAPPING_SETTING_STATISTICS_H__
#ifdef __cplusplus
#include <string>
#include <map>
#include "KeepingModifyUtilitys.h"
#define STATISTAC_RECORD_COUNT_FLAG_ADD 1
#define STATISTAC_RECORD_COUNT_FLAG_MINUS 0
class MappingSettingStatistics {
public:
MappingSettingStatistics(std::string fileName);
~MappingSettingStatistics(){}
int loadStatisticsRecord();
int updateStatisticsRecord(ParametersItem *paramItem); //添加一条完整的记录,包括paramName,earliestTimeStamp,recordCount
int unloadStatisticsRecord();
bool modifyStatisticsRecordTimeStamps(std::string& name, std::string& timeStamp); //修改paramName对应的earliestTimeStamp
std::string getStatisticsRecordTimeStamps(std::string& name);
int modifyStatisticsRecordCount(std::string& name, int IsFlagAdd, int step); //修改paramName对应的recordCount
int getStatisticsRecordCount(std::string& name);
std::map<std::string, ParamStatistics> getStatisticsRecordMap();
int statisticsRecordMapOutput();
private:
std::map<std::string, ParamStatistics> m_paramStatisticsMap; // 维护一个已修改参数的信息映射表,参数信息均来源于 PARAM_CHANGE_RECORD_KEEPING_FILE_PATH 文件中;
std::string m_filePath;
int m_RecordFileAvailable;
};
#endif // __cplusplus
#endif //__MAPPING_SETTING_STATISTICS_H__
MappingSettingStatistics.cpp源码如下:
#include <iostream>
#include <algorithm>
#include <fstream>
#include <sstream>
#include "Log/LogC.h"
#include "logSettings.h"
#include "ThreadMutex.h"
#include "MappingSettingStatistics.h"
using namespace std;
static int gIsDeleteFlag = 0;
MappingSettingStatistics::MappingSettingStatistics(std::string fileName)
: m_filePath(fileName)
{
m_RecordFileAvailable = 0;
settingsLogVerbose(" initial.\n");
}
/**
* @Func: loadStatisticsRecord
* ps.: 逐行从 config_param_modify.record 文件加载到 m_paramStatisticsMap
* @Param:
* @Return: int
*
**/
int MappingSettingStatistics::loadStatisticsRecord()
{
FILE *fp = NULL;
char ch;
std::string line("");
settingsLogVerbose("\n");
std::ifstream fin(m_filePath.c_str(), std::ios::in);
while(std::getline(fin, line)) {
if (!m_RecordFileAvailable) { //清除第一行
m_RecordFileAvailable = 1;
std::string::size_type position = line.find('=');
if (position != std::string::npos) {
settingsLogVerbose("Will jump the line[%s].\n", line.c_str());
line.clear();
continue;
}
settingsLogWarning("The available information is not found.(%s)\n", line.c_str());
break;
}
settingsLogVerbose("Start parse the line[%s].\n", line.c_str());
updateStatisticsRecord(parseRecordLine(line)); //逐行添加
line.clear();
}
settingsLogVerbose("Load \"%s\" ok.\n", m_filePath.c_str());
return 0;
}
/**
* @Func: updateStatisticsRecord
* ps. :将逐行解析到的 添加到 m_paramStatisticsMap
* @Param: paramItem, type:: ParametersItem *
* @Return: int
*
**/
int MappingSettingStatistics::updateStatisticsRecord(ParametersItem *paramItem)
{
ParamStatistics *paramStatistic = new ParamStatistics();
std::map<std::string, ParamStatistics>::iterator paramStatisticIt = m_paramStatisticsMap.find(paramItem->paramName);
if( (paramItem->paramName).compare(ERROR_PARAM_ITEM.paramName) == 0
|| (paramItem->paramName).empty() || (paramItem->modifyTimeStamp).empty()){
settingsLogError("paramItem[%p], paramName[%s] modifyTimeStamp[%s].\n", paramItem, paramItem->paramName.c_str(), paramItem->modifyTimeStamp.c_str());
return -1;
}
paramStatistic->paramName = paramItem->paramName;
paramStatistic->earliestTimeStamp = paramItem->modifyTimeStamp;
settingsLogVerbose("INPUT: paramName[%s] modifyTimeStamp[%s].\n", paramStatistic->paramName.c_str(), paramStatistic->earliestTimeStamp.c_str());
//判断字段是否在统计列表 m_paramStatisticsMap
if (paramStatisticIt != m_paramStatisticsMap.end()){ //找到
settingsLogVerbose("ISFIND: recordCount[%d], earliestTimeStamp[%s]\n", (paramStatisticIt->second).recordCount, (paramStatisticIt->second).earliestTimeStamp.c_str());
if(dateTimeCompare((paramStatisticIt->second).earliestTimeStamp, paramStatistic->earliestTimeStamp) > 0){ //时间早于m_paramStatisticsMap中的时间戳
paramStatistic->recordCount = (paramStatisticIt->second).recordCount;
m_paramStatisticsMap[paramStatistic->paramName] = *paramStatistic;
}
} else { //未找到
paramStatistic->recordCount = 0;
m_paramStatisticsMap[paramStatistic->paramName] = *paramStatistic;
settingsLogError("\n");
}
modifyStatisticsRecordCount(paramStatistic->paramName, STATISTAC_RECORD_COUNT_FLAG_ADD, 1);
settingsLogVerbose("Has update OK.\n");
/* settingsLogVerbose("updateStatisticsRecord paramStatistic->paramName[%s] paramStatistic->earliestTimeStamp[%s] paramStatistic->recordCount[%d].\n",
(paramStatistic->paramName).c_str(), (paramStatistic->earliestTimeStamp).c_str(), paramStatistic->recordCount
);
*/
return 0;
}
/**
* @Func: unloadStatisticsRecord
* @Param:
* @Return: std::string
*
**/
int MappingSettingStatistics::unloadStatisticsRecord()
{
if(m_paramStatisticsMap.empty()){
settingsLogError("unloadStatisticsRecord:: m_paramStatisticsMap has been empty, ERROR.\n");
return -1;
}
m_paramStatisticsMap.erase(m_paramStatisticsMap.begin(), m_paramStatisticsMap.end());
settingsLogVerbose("Has unload OK.\n");
return 0;
}
/**
* @Func: modifyStatisticsRecordTimeStamps
* ps. :从文件 m_fileName 的每一行中得到所需的字段值
* @Param: name, type:: std::string&
* value, type:: std::string&
* @Return: bool
*
**/
bool MappingSettingStatistics::modifyStatisticsRecordTimeStamps(std::string& name, std::string& timeStamp)
{
if( name.compare(ERROR_PARAM_ITEM.paramName) == 0
|| name.empty() || timeStamp.empty()){
settingsLogError("paramName[%s] modifyTimeStamp[%s].\n", name.c_str(), timeStamp.c_str());
return false;
}
std::map<std::string, ParamStatistics>::iterator paramStatisticIt = m_paramStatisticsMap.find(name);
settingsLogVerbose("SET: name[%s], TimeStamp[%s]\n", name.c_str(), timeStamp.c_str());
if (paramStatisticIt != m_paramStatisticsMap.end()){ //找到
settingsLogVerbose("HASFIND: earliestTimeStamp[%s]\n", (paramStatisticIt->second).earliestTimeStamp.c_str());
m_paramStatisticsMap[name].earliestTimeStamp = timeStamp;
} else { //未找到
settingsLogVerbose("m_paramStatisticsMap cannot find param[%s].\n", name.c_str());
return false;
}
settingsLogVerbose("Has modify TimeStamps OK.\n");
return true;
}
/**
* @Func: getStatisticsRecordTimeStamps
* @Param: name, type:: std::string&
* @Return: std::string
*
**/
std::string MappingSettingStatistics::getStatisticsRecordTimeStamps(std::string& name)
{
std::string timeStamp("");
std::map<std::string, ParamStatistics>::iterator paramStatisticIt = m_paramStatisticsMap.find(name);
if (paramStatisticIt != m_paramStatisticsMap.end()){ //找到
timeStamp = m_paramStatisticsMap[name].earliestTimeStamp;
} else { //未找到
settingsLogError("m_paramStatisticsMap cannot find param[%s].\n", name.c_str());
}
settingsLogVerbose("GET: name[%s], TimeStamp[%s]\n", name.c_str(), timeStamp.c_str());
return timeStamp;
}
/**
* @Func: modifyStatisticsRecordCount
* @Param: name, type:: std::string&
* IsFlagAdd, type:: int
* step, type:: int
* @Return: int
*
**/
int MappingSettingStatistics::modifyStatisticsRecordCount(std::string& name, int IsFlagAdd, int step)
{
if( name.compare(ERROR_PARAM_ITEM.paramName) == 0 || name.empty()){
settingsLogError("paramName[%s] modifyTimeStamp[%s].\n", name.c_str());
return -1;
}
std::map<std::string, ParamStatistics>::iterator paramStatisticIt = m_paramStatisticsMap.find(name);
settingsLogVerbose("SET: name[%s], flag[%d], step[%d]\n", name.c_str(), IsFlagAdd, step);
if (paramStatisticIt != m_paramStatisticsMap.end()){ //找到
if(IsFlagAdd == STATISTAC_RECORD_COUNT_FLAG_ADD){ //add
settingsLogVerbose("HASFIND: recordCount[%d].\n", (paramStatisticIt->second).recordCount);
(paramStatisticIt->second).recordCount = (paramStatisticIt->second).recordCount + 1;
}else if(IsFlagAdd == STATISTAC_RECORD_COUNT_FLAG_MINUS){ //minus
settingsLogVerbose("HASFIND: recordCount[%d] step[%d].\n",(paramStatisticIt->second).recordCount, step);
(paramStatisticIt->second).recordCount = (paramStatisticIt->second).recordCount - step;
}else{
settingsLogError("m_paramStatisticsMap IsFlagAdd is[%d] ERROR.\n", IsFlagAdd);
return -1;
}
} else {
settingsLogError("m_paramStatisticsMap cannot find param[%s].\n", name.c_str());
return -1;
}
settingsLogVerbose("Has modify RecordCount OK.\n");
return 0;
}
/**
* @Func: getStatisticsRecordCount
* @Param: name, type:: std::string&
* @Return: int
*
**/
int MappingSettingStatistics::getStatisticsRecordCount(std::string& name)
{
if( name.compare(ERROR_PARAM_ITEM.paramName) == 0 || name.empty()){
settingsLogError("paramName[%s] modifyTimeStamp[%s].\n", name.c_str());
return -1;
}
int count = 0;
std::map<std::string, ParamStatistics>::iterator paramStatisticIt = m_paramStatisticsMap.find(name);
if (paramStatisticIt != m_paramStatisticsMap.end()){ //找到
count = (paramStatisticIt->second).recordCount;
} else {
settingsLogError("m_paramStatisticsMap cannot find param[%s].\n", name.c_str());
return -1;
}
settingsLogVerbose("GET: name[%s], count[%d]\n", name.c_str(), count);
return count;
}
/**
* @Func: getStatisticsRecordMap
* @Param:
* @Return: std::map<std::string, ParamStatistics>
*
**/
std::map<std::string, ParamStatistics> MappingSettingStatistics::getStatisticsRecordMap()
{
settingsLogVerbose("getStatisticsRecordMap.\n");
return m_paramStatisticsMap;
}
/**
* @Func: statisticsRecordMapOutput
* @Param:
* @Return: int
*
**/
int MappingSettingStatistics::statisticsRecordMapOutput()
{
std::map<std::string, ParamStatistics>::iterator paramStatisticIt;
for(paramStatisticIt = m_paramStatisticsMap.begin(); paramStatisticIt != m_paramStatisticsMap.end(); ++paramStatisticIt)
cout << "statisticsRecordMapOutput:: key:"<< paramStatisticIt->first << " earliestTimeStamp:" << (paramStatisticIt->second).earliestTimeStamp << " recordCount:" << (paramStatisticIt->second).recordCount <<endl;
return 0;
}
4,参数关键字过滤器功能:SensitiveParamFiltering类
SensitiveParamFiltering.h如下:
#ifndef __SENSITIVE_PARAM_FILTERING_H__
#define __SENSITIVE_PARAM_FILTERING_H__
#ifdef __cplusplus
#include <string>
#include <vector>
#include <map>
class SensitiveParamFiltering { /* 敏感词过滤 */
public:
SensitiveParamFiltering();
~SensitiveParamFiltering(){}
bool filteringSensitiveParam(std::string param); //在构造时初始化敏感字段,在需要时通过该方法剔除敏感字段
bool addSensitiveParam(std::string& param);
int sensitiveParamFilterOutput();
private:
std::vector<std::string> m_sensitiveParamFilter; //保存需要过滤的敏感字段,在构造操作时初始化
};
extern "C" SensitiveParamFiltering gSensitiveParamFilter;
#endif // __cplusplus
#endif //__SENSITIVE_PARAM_FILTERING_H__
SensitiveParamFiltering.cpp源码如下:
#include <iostream>
#include <stdio.h>
#include "Log/LogC.h"
#include "logSettings.h"
#include "ThreadMutex.h"
#include "SensitiveParamFiltering.h"
using namespace std;
extern "C" {
SensitiveParamFiltering gSensitiveParamFilter;
}
static std::string gSensitiveListStr[] = {"ntvpasswd", "ntvAESpasswd", "defContPwd", "defAESContpwd",
"netpasswd", "syncntvpasswd", "syncntvAESpasswd", "netAESpasswd", "dhcppasswd", "ipoeAESpasswd", "wifi_password",
"authbg_md5", "bootlogo_md5",
"Device.ManagementServer.Password",
"Device.ManagementServer.ConnectionRequestPassword",
"Device.ManagementServer.STUNPassword"
};
SensitiveParamFiltering::SensitiveParamFiltering()
{
settingsLogVerbose("\n");
int i = 0;
for(i = 0; i < 16; i++){
//m_sensitiveParamFilter.push_back(gSensitiveListStr[i]);
}
}
/**
* @Func: filteringSensitiveParam
* @Param: param, type:: std::string
* @Return: bool
*
**/
bool SensitiveParamFiltering::filteringSensitiveParam(std::string param)
{
std::vector<std::string>::iterator it;
for (it = m_sensitiveParamFilter.begin(); it != m_sensitiveParamFilter.end(); ++it) {
if ((*it).compare(param) == 0)
return true;
}
return false;
}
/**
* @Func: addSensitiveParam
* @Param: param, type:: std::string
* @Return: bool
*
**/
bool SensitiveParamFiltering::addSensitiveParam(std::string& param)
{
if(param.empty()){
settingsLogError("param[%s] cannot empty, ERROR.\n", param.c_str());
return false;
}
m_sensitiveParamFilter.push_back(param);
return true;
}
/**
* @Func: sensitiveParamFilterOutput
* @Param:
* @Return: int
*
**/
int SensitiveParamFiltering::sensitiveParamFilterOutput()
{
std::vector<std::string>::iterator it;
for (it = m_sensitiveParamFilter.begin(); it != m_sensitiveParamFilter.end(); ++it)
cout << "sensitiveParamFilterOutput:: key: " << *it <<endl;
return 0;
}
5,模块中所需的其他功能:
KeepingModifyUtilitys.h源码:
#ifndef __KEEPING_MODIFY_UTILITY_H__
#define __KEEPING_MODIFY_UTILITY_H__
#ifdef __cplusplus
#include <string>
#define COUNT_OF_PARAM_IN_MODIFY_FILE_MAX 10
#define PARAM_CHANGE_RECORD_KEEPING_VERSION "1.0"
#define STRING_ERROR "string error"
typedef struct _DateTimeStamp {
uint16_t mYear; //!< e.g. 2005
uint8_t mMonth; //!< 1..12
uint8_t mDayOfWeek; //!< 0..6, 0==Sunday
uint8_t mDay; //!< 1..31
uint8_t mHour; //!< 0..23
uint8_t mMinute; //!< 0..59
uint8_t mSecond; //!< 0..59
} DateTimeStamp;
void getDateTimeStamp(DateTimeStamp* dt);
typedef enum {
RecordChangedSource_Reserved = 0,
RecordChangedSource_STBMonitor,
RecordChangedSource_tr069Manager,
RecordChangedSource_JsLocalSetting,
RecordChangedSource_JsEpgSetting,
RecordChangedSource_Other,
RecordChangedSource_Unknow
} RecordChangedSource;
typedef struct _ParametersItem {
std::string paramName; //修改的谁
std::string oldValue; //原来的值是什么
std::string newValue; //被修改成什么值
std::string modifyTimeStamp; //什么时间修改的
std::string sourceModule; //谁来修改的
std::string modifiedFile; //被修改的谁是哪个文件中的
} ParametersItem;
typedef struct _ParamStatistics{
std::string paramName; //paramName, 字段名
std::string earliestTimeStamp; //earliestTimeStamp, record文件中paramName字段的最早记录
int recordCount; //recordCount, record文件中paramName字段的记录次数
} ParamStatistics;
extern "C" ParametersItem ERROR_PARAM_ITEM;
extern "C" std::string gMonthStr[12 + 1];
int dateTimeCompare(std::string& strBaseDTime, std::string& strNowDTime);
std::string getValueByTag(std::string& str, const char *tag);
ParametersItem* parseRecordLine(std::string& strLine);
#endif // __cplusplus
#endif //__KEEPING_MODIFY_UTILITY_H__
KeepingModifyUtilitys.cpp代码如下:
#include <iostream>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <vector>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include "Log/LogC.h"
#include "logSettings.h"
#include "ThreadMutex.h"
#include "KeepingModifyUtilitys.h"
using namespace std;
extern "C" {
ParametersItem ERROR_PARAM_ITEM = {"string error", "string error", "string error", "string error", "string error", "string error"};
std::string gMonthStr[13] = {"Undefined", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
}
void getDateTimeStamp(DateTimeStamp* dt)
{
settingsLogVerbose("GetDateTime.\n");
if (dt) {
struct timeval current;
struct tm temp_time;
if (!gettimeofday(¤t, NULL)){
localtime_r(¤t.tv_sec, &temp_time);
dt->mYear = temp_time.tm_year + 1900;
dt->mMonth = temp_time.tm_mon + 1;
dt->mDayOfWeek = temp_time.tm_wday;
dt->mDay = temp_time.tm_mday;
dt->mHour = temp_time.tm_hour;
dt->mMinute = temp_time.tm_min;
dt->mSecond = temp_time.tm_sec;
}
}
return ;
}
/**
* @Func: dateTimeCompare
* @Param: strBaseDTime, type:: std::string&
* strNowDTime, type:: std::string&
* @Return: int
*
* e.g: <2012-Jan-01 08:02:05.521> <2012-Jan-06 08:04:50.147>.
**/
int dateTimeCompare(std::string& strBaseDTime, std::string& strNowDTime) //(const char* dtime1, const char* dtime2) //
{
if(strBaseDTime.empty() || strNowDTime.empty()){
settingsLogError("strBaseDTime is NULL.\n");
return -1;
}
int i = 0;
std::string strBaseTime(""), strBaseDate(""), strBaseYear(""), strBaseMonth(""), strBaseDay("");
std::string strNowTime(""), strNowDate(""), strNowYear(""), strNowMonth(""), strNowDay("");
std::string strBaseSubDate("");
std::string::size_type pos1, pos2;
std::vector<std::string> vectorMonth;
settingsLogVerbose("strBaseDTime[%s] strNowDTime[%s].\n", strBaseDTime.c_str(), strNowDTime.c_str());
for(i = 0; i < 13; i++){
vectorMonth.push_back(gMonthStr[i]);
}
//get Date && Time
pos1 = strBaseDTime.find(" ");
strBaseDate = strBaseDTime.substr(0, pos1);
strBaseTime = strBaseDTime.substr(pos1 + 1, strBaseDTime.length());
pos1 = strBaseDate.find("-");
strBaseYear = strBaseDate.substr(0, pos1);
strBaseSubDate = strBaseDate.substr(pos1 + 1, strBaseDate.length());
pos1 = strBaseSubDate.find("-");
strBaseMonth = strBaseSubDate.substr(0, pos1);
strBaseDay = strBaseSubDate.substr(pos1 + 1, strBaseSubDate.length());
pos2 = strNowDTime.find(" ");
strNowDate = strNowDTime.substr(0, pos2);
strNowTime = strNowDTime.substr(pos2 + 1, strNowDTime.length());
pos2 = strNowDate.find("-");
strNowYear = strNowDate.substr(0, pos2);
strBaseSubDate = strNowDate.substr(pos2 + 1, strNowDate.length());
pos2 = strBaseSubDate.find("-");
strNowMonth = strBaseSubDate.substr(0, pos2);
strNowDay = strBaseSubDate.substr(pos2 + 1, strBaseSubDate.length());
//compare Date && Time
if(strBaseYear.compare(strNowYear) == 0){ //year
if(std::find(vectorMonth.begin(), vectorMonth.end(), strBaseMonth) == std::find(vectorMonth.begin(), vectorMonth.end(), strNowMonth)){ //month
if(strBaseDay.compare(strNowDay) == 0){ //day
if(strBaseTime.compare(strNowTime) == 0){ //time
settingsLogVerbose("strBaseDTime[%s] == strNowDTime[%s].\n", strBaseDTime.c_str(), strNowDTime.c_str());
return 0;
} else if(strBaseTime.compare(strNowTime) > 0){ //time
settingsLogVerbose("strBaseTime[%s] > strNowTime[%s].\n", strBaseTime.c_str(), strNowTime.c_str());
return 1;
} else { //time
settingsLogVerbose("strBaseTime[%s] < strNowTime[%s].\n", strBaseTime.c_str(), strNowTime.c_str());
return -1;
}
} else if(strBaseDay.compare(strNowDay) > 0){ //day
settingsLogVerbose("strBaseDay[%s] > strNowDay[%s].\n", strBaseDay.c_str(), strNowDay.c_str());
return 1;
} else { //day
settingsLogVerbose("strBaseDay[%s] < strNowDay[%s].\n", strBaseDay.c_str(), strNowDay.c_str());
return -1;
}
} else if(std::find(vectorMonth.begin(), vectorMonth.end(), strBaseMonth) > std::find(vectorMonth.begin(), vectorMonth.end(), strNowMonth)){ //month
settingsLogVerbose("strBaseMonth[%s] > strNowMonth[%s].\n", strBaseMonth.c_str(), strNowMonth.c_str());
return 1;
} else { //month
settingsLogVerbose("strBaseMonth[%s] < strNowMonth[%s].\n", strBaseMonth.c_str(), strNowMonth.c_str());
return -1;
}
} else if(strBaseYear.compare(strNowYear) > 0){ //year
settingsLogVerbose("strBaseYear[%s] < strNowYear[%s].\n", strBaseYear.c_str(), strNowYear.c_str());
return 1;
} else { //(strBaseYear.compare(strNowDate) < 0)//year
settingsLogVerbose("strBaseYear[%s] < strNowYear[%s].\n", strBaseYear.c_str(), strNowYear.c_str());
return -1;
}
settingsLogVerbose("strBaseDTime[%s] strNowDTime[%s], ERROR.\n", strBaseDTime.c_str(), strNowDTime.c_str());
return -2;
}
/**
* @Func: getValueByTag
* ps. :从文件 m_fileName 的每一行中得到所需的字段值
* @Param: str, type:: std::string&
* tag, type:: const char *
* @Return: std::string
*
* e.g: <2012-Jan-01 08:02:05.521>
**/
std::string getValueByTag(std::string& str, const char *tag)
{
std::string::size_type position;
std::string value("");
std::string strTag = tag;
position = str.find(strTag);
if (position == std::string::npos) {
settingsLogError("Str[%s] cannot find strTag[%s], ERROR.\n", str.c_str(), strTag.c_str());
return "fail";
}
value = str.substr(0, position);
str = str.substr(std::string(strTag).size() + value.size(), str.size());
return value;
}
/**
* @Func: parseRecordLine
* ps. :从文件 m_fileName 的每一行中得到所需的字段值
* @Param: strLine, type:: std::string&
* @Return: ParametersItem*, a structure;
*
* e.g: Parameter[ hd_aspect_mode ] @<2012-Jan-01 08:02:05.481> modified by[ JS ]from[ 2 ]to[ 0 ]into file[ /root/yx_config_customer.ini ].
**/
ParametersItem* parseRecordLine(std::string& strLine)
{
ParametersItem *paramItem = new ParametersItem();
if(strLine.find("Parameter[") == std::string::npos){
settingsLogError("parseRecordLine strLine[%s]\n", strLine.c_str());
return &ERROR_PARAM_ITEM;
}
strLine = strLine.substr(std::string("Parameter[ ").size(), strLine.size());
paramItem->paramName = getValueByTag(strLine, " ] @<");
if (paramItem->paramName == "fail")
return &ERROR_PARAM_ITEM;
paramItem->modifyTimeStamp = getValueByTag(strLine, "> modified by[ ");
if (paramItem->modifyTimeStamp == "fail")
return &ERROR_PARAM_ITEM;
paramItem->sourceModule = getValueByTag(strLine, " ]from[ ");
if (paramItem->sourceModule == "fail")
return &ERROR_PARAM_ITEM;
paramItem->oldValue = getValueByTag(strLine, " ]to[ ");
if (paramItem->oldValue == "fail")
return &ERROR_PARAM_ITEM;
paramItem->newValue = getValueByTag(strLine, " ]into file[ ");
if (paramItem->newValue == "fail")
return &ERROR_PARAM_ITEM;
paramItem->modifiedFile = getValueByTag(strLine, " ].");
if (paramItem->modifiedFile == "fail")
return &ERROR_PARAM_ITEM;
/* settingsLogVerbose("parseRecordLine paramItem.paramName[%s] newValue[%s] sourceModule[%s] oldValue[%s] modifyTimeStamp[%s] modifiedFile[%s].\n",
(paramItem->paramName).c_str(), (paramItem->newValue).c_str(), (paramItem->sourceModule).c_str(),
(paramItem->oldValue).c_str(), (paramItem->modifyTimeStamp).c_str(), (paramItem->modifiedFile).c_str()
);
*/
return paramItem;
}