提交 6238dabd 编写于 作者: W wangguibao

20190213

上级 184c7612
......@@ -93,4 +93,7 @@ if(WITH_MKLDNN)
endif()
add_subdirectory(bsl)
add_subdirectory(ullib)
add_subdirectory(spreg)
add_subdirectory(configure)
add_subdirectory(predictor)
......@@ -7,8 +7,13 @@ add_custom_command(TARGET copy_bsl_headers
# COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/include/bsl/containers && cp ${CMAKE_CURRENT_LIST_DIR}/containers/*.h ${CMAKE_CURRENT_BINARY_DIR}/include/bsl/containers
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/include/bsl/check_cast && cp ${CMAKE_CURRENT_LIST_DIR}/check_cast/*.h ${CMAKE_CURRENT_BINARY_DIR}/include/bsl/check_cast
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/include/bsl/ResourcePool && cp ${CMAKE_CURRENT_LIST_DIR}/ResourcePool/*.h ${CMAKE_CURRENT_BINARY_DIR}/include/bsl/ResourcePool
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/include/bsl/var/ && cp ${CMAKE_CURRENT_LIST_DIR}/var/utils/*.h ${CMAKE_CURRENT_BINARY_DIR}/include/bsl/var/
COMMAND cp ${CMAKE_CURRENT_LIST_DIR}/var/interface/*.h ${CMAKE_CURRENT_BINARY_DIR}/include/bsl/var/
COMMAND cp ${CMAKE_CURRENT_LIST_DIR}/var/implement/*.h ${CMAKE_CURRENT_BINARY_DIR}/include/bsl/var/
COMMAND cp ${CMAKE_CURRENT_LIST_DIR}/check_cast/*.h ${CMAKE_CURRENT_BINARY_DIR}/include/bsl
COMMAND cp ${CMAKE_CURRENT_LIST_DIR}/ResourcePool/*.h ${CMAKE_CURRENT_BINARY_DIR}/include/bsl/
)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
add_subdirectory(utils)
add_subdirectory(alloc)
add_subdirectory(archive)
......@@ -21,3 +26,6 @@ add_subdirectory(ResourcePool)
add_subdirectory(var/interface)
add_subdirectory(var/utils)
add_subdirectory(var/implement)
add_custom_target(bsl)
add_dependencies(bsl utils alloc archive containers pool buffer exception
check_cast ResourcePool interface var_utils implement)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
add_custom_target(alloc)
......@@ -4,3 +4,4 @@ add_subdirectory(hash)
add_subdirectory(list)
add_subdirectory(slist)
add_subdirectory(string)
add_custom_target(containers)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_custom_target(interface)
......@@ -57,7 +57,7 @@ ExternalProject_Add(
-DCMAKE_INSTALL_LIBDIR:PATH=${PADDLE_INSTALL_DIR}/lib
-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON
-DCMAKE_BUILD_TYPE:STRING=${THIRD_PARTY_BUILD_TYPE}
BUILD_COMMAND make && make inference_lib_dist
INSTALL_COMMAND make inference_lib_dist
)
ADD_LIBRARY(paddle_fluid STATIC IMPORTED GLOBAL)
SET_PROPERTY(TARGET paddle_fluid PROPERTY IMPORTED_LOCATION ${PADDLE_LIBRARIES})
......
#edit-mode: -*- python -*-
#coding:gbk
#工作路径.
WORKROOT('../../')
CC('g++')
#C预处理器参数.
#CPPFLAGS('-D_GNU_SOURCE -D__STDC_LIMIT_MACROS -DVERSION=\\\"1.9.8.7\\\"')
#C编译参数.
CFLAGS('-pipe -fsigned-char -Wall -W -g -fPIC -Woverloaded-virtual')
#C++编译参数.
CXXFLAGS('-pipe -fsigned-char -Wall -W -g -fPIC -Woverloaded-virtual')
#IDL编译参数
#IDLFLAGS('--compack')
#UBRPC编译参数
#UBRPCFLAGS('--compack')
#头文件路径.
INCPATHS('. compiler/src')
#使用库
#LIBS('./libconfigure.a')
#链接参数.
#LDFLAGS('-lpthread -lcrypto -lrt')
#依赖模块
CONFIGS('lib2-64/bsl@bsl_1-1-8-0_PD_BL')
CONFIGS('lib2-64/ullib@ullib_3-1-43-2_PD_BL')
CONFIGS('public/spreg@spreg_1-0-3-0_PD_BL')
CONFIGS('third-64/pcre@pcre_7-7-0-0_PD_BL')
user_sources='FileReloader.cpp ConfigReloader.cpp CmdOption.cpp ConfigError.cpp ConfigGroup.cpp ConfigUnit.cpp Configure.cpp constraint/Constraint.cpp constraint/ConstraintFunction.cpp constraint/cc_default.cpp reader/RawData.cpp reader/Reader.cpp utils/init.cpp utils/trans.cpp cfgext.cpp cfgflag.cpp compiler/src/idl.c compiler/src/idl_lex.c compiler/src/idl_gram.c'
user_headers='ConfigGroup.h Configure.h ConfigReloader.h ConfigArray.h cfgext.h CmdOption.h ConfigUnit.h ConfigError.h FileReloader.h EnvGet.h cfgflag.h'
HEADERS('utils/*.h', '$INC/utils')
HEADERS('constraint/*.h', '$INC/constraint')
HEADERS('compiler/src/idl_conf_if.h', '$INC')
#可执行文件
#Application('configure',Sources(user_sources))
#静态库
StaticLibrary('config',Sources(user_sources),HeaderFiles(user_headers))
#共享库
#SharedLibrary('configure',Sources(user_sources),HeaderFiles(user_headers))
#子目录
#Directory('demo')
LIST(APPEND configure_srcs
${CMAKE_CURRENT_LIST_DIR}/FileReloader.cpp
${CMAKE_CURRENT_LIST_DIR}/ConfigReloader.cpp
${CMAKE_CURRENT_LIST_DIR}/CmdOption.cpp
${CMAKE_CURRENT_LIST_DIR}/ConfigError.cpp
${CMAKE_CURRENT_LIST_DIR}/ConfigGroup.cpp
${CMAKE_CURRENT_LIST_DIR}/ConfigUnit.cpp
${CMAKE_CURRENT_LIST_DIR}/Configure.cpp
${CMAKE_CURRENT_LIST_DIR}/constraint/Constraint.cpp
${CMAKE_CURRENT_LIST_DIR}/constraint/ConstraintFunction.cpp
${CMAKE_CURRENT_LIST_DIR}/constraint/cc_default.cpp
${CMAKE_CURRENT_LIST_DIR}/reader/RawData.cpp
${CMAKE_CURRENT_LIST_DIR}/reader/Reader.cpp
# ${CMAKE_CURRENT_LIST_DIR}/utils/init.cpp
${CMAKE_CURRENT_LIST_DIR}/utils/trans.cpp
${CMAKE_CURRENT_LIST_DIR}/cfgext.cpp
${CMAKE_CURRENT_LIST_DIR}/cfgflag.cpp
${CMAKE_CURRENT_LIST_DIR}/compiler/src/idl.c
${CMAKE_CURRENT_LIST_DIR}/compiler/src/idl_lex.c
${CMAKE_CURRENT_LIST_DIR}/compiler/src/idl_gram.c
)
add_library(configure ${configure_srcs})
add_dependencies(configure bsl brpc ullib spreg)
target_include_directories(configure PUBLIC
${CMAKE_CURRENT_LIST_DIR}/
${CMAKE_CURRENT_LIST_DIR}/compiler/src
${CMAKE_CURRENT_LIST_DIR}/../ullib/include
${CMAKE_CURRENT_LIST_DIR}/../spreg/
${CMAKE_CURRENT_BINARY_DIR}/../bsl/include)
1.2.0
* add configUnit的写支持。add_unit/copy_unit/del_unit/set_value
1.1.0
* add 增加热加载支持. ConfigReloader/FileReloader
1.0.7
* fix 消除多线程so使用中析构两次error_unit的问题
1.0.6
* fix loadIVar时不给非特殊字符串增加引号
* add 支持对configure对象进行约束检查. configure.check_once
1.0.5
* fix 解决configure和idlcompiler的命名冲突问题
* fix Configure::loadIVar中,整数和浮点类型的IVar转成的字符串中去掉双引号
* fix 将int32等类型定义改成带comcfg_前缀的命名,避免和别处的定义冲突。
* fix error unit改成单例模式
* fix 解决-Woverloaded-virtual编译参数引起编译warning的问题
* add 增加遍历接口get_sub_unit(),配合size()和selfType()可以完成对configure的遍历
* add 增加接口get_key_name(),获取key的名字
1.0.4
* fix getErrKeyPath方法增加const修饰,并从Configure中移到ConfigUnit中。
* add 抛出的Exception中增加出错路径信息
* add 增加NOSUCHKEY以外的各种读配置错误的具体路径信息。包括:1).
OUTOFRANGE 超出范围;2). FORMATERROR 格式错误;3). NULLVALUE 值为空;4).
NULLBUFFER 传出参数指针为NULL;5). GROUPTOUNIT 使用group的取值方法
1.0.3.1 nsfw 2009/08/07
* fix 修复autoConfigGen函数中的内存泄露
* fix autoConfigGen()对数组改成只生成一份配置,一份注释的配置
* add 增加Configure::getErrKeyPath()接口,获取不存在的key失败时,返回导致出错的key具体路径。
* add 增加to_xxx系列提供默认值的重载函数
* add 增加ConfigUnit::deepGet()接口,长路径的直接获取
* add 增加读取环境变量的宏
/***************************************************************************
*
* Copyright (c) 2008 Baidu.com, Inc. All Rights Reserved
* $Id: CmdOption.cpp,v 1.6 2009/11/10 04:50:30 scmpf Exp $
*
**************************************************************************/
/**
* @file CmdOption.cpp
* @author yingxiang(com@baidu.com)
* @date 2008/12/29 21:50:42
* @version $Revision: 1.6 $
* @brief
*
**/
#include "CmdOption.h"
#include "ConfigUnit.h"
#include "utils/cc_utils.h"
#include <string.h>
namespace comcfg{
CmdOption :: CmdOption(){
}
int CmdOption :: setOptString(const char * p){
int ret = 0;
const char *prev = NULL;
memset(ch, 0, sizeof(ch));
while(*p != '\0'){
if(*p == ':'){
if(prev == NULL || ch[(unsigned char)(*prev)] == CMD_OPT2){
ret = -1;
break;
}
else{
++ ch[(unsigned char)(*prev)];
}
}
else{
if(ch[(unsigned char)(*p)]){
ret = -1;
break;
}
ch[(unsigned char)(*p)] = CMD_OPT0;
}
prev = p;
++p;
}
return ret;
}
int CmdOption :: init(int argc, char * const * argv, const char * optstring){
if(argv == NULL || optstring == NULL){
LOG(WARNING) << "Null pointer in CmdOption::init.....";
return -1;
}
if(setOptString(optstring) != 0){
LOG(WARNING) << "optstring error.";
return -1;
}
int ret = 0;
//
try{
for(int i = argc - 1; i >= 0; --i){
if(argv[i][0] == '-'){
str_t key, value;
//option
if(argv[i][1] == '-'){
//long option
key = argv[i] + 2;
size_t sz;// = key.find('=', 0);
for(sz = 0; sz < key.size(); ++sz){
if(key[sz] == '='){
break;
}
}
if(sz != key.size()){
value = key.substr(sz+1);
key = key.substr(0, sz);
LOG(INFO) << "[CmdOption init - long opt] key=" << key.c_str() << " value=" << value.c_str();
}
if( push(key, new ConfigUnit(key, value, NULL, this)) ){
ret = -1;
}
}
else if(ch[(unsigned char)(argv[i][1])] == CMD_OPT0){
//opt 0
key = "";
key.push_back(argv[i][1]);
if( push(key, new ConfigUnit(key, value, NULL, this)) ){
ret = -1;
}
}
else if(ch[(unsigned char)(argv[i][1])] == CMD_OPT1){
//opt 1
key = "";
key.push_back(argv[i][1]);
value = argv[i] + 2;
if(value.size() == 0){
if(arg.size() == 0){
LOG(WARNING) << "Option [-" << argv[i][1] << ":] without any argument.";
ret = -1;
}
else{
value = arg[arg.size() - 1];
arg.pop_back();
}
}
if( push(key, new ConfigUnit(key, value, NULL, this)) ){
ret = -1;
}
}
else if(ch[(unsigned char)(argv[i][1])] == CMD_OPT2){
//opt 2
key = "";
key.push_back(argv[i][1]);
value = argv[i] + 2;
if(value.size() == 0){
LOG(WARNING) << "Option [-" << argv[i][1] << "::] without any argument.";
ret = -1;
}
if( push(key, new ConfigUnit(key, value, NULL, this)) ){
ret = -1;
}
}
else{
LOG(WARNING) << "Option [-" << argv[i][1] << "] unknown.";
ret = -1;
}
}
else{
arg.push_back(str_t(argv[i]));
}
}
}
catch(...){
LOG(WARNING) << "Option error..";
ret = -1;
}
return ret;
}
bool CmdOption :: hasOption(const char * s) const {
return (*this)[s].selfType() != CONFIG_ERROR_TYPE;
}
size_t CmdOption :: argSize() const {
return arg.size();
}
const char * CmdOption :: getArg(int n) const {
if(n >= (int)arg.size()){
return NULL;
}
//
return arg[(int)arg.size() - n - 1].c_str();
}
int CmdOption :: registHook(const char * option, hook_t hook){
pair_t p;
p.first = str_t(option);
p.second = hook;
hkmap.insert(p);
return 0;
}
int CmdOption :: runHook(){
itr_t itr;
for(itr = fieldMap.begin(); itr != fieldMap.end(); ++itr){
hk_pair_t p = hkmap.equal_range(itr->first);
for(hkitr_t hkitr = p.first; hkitr != p.second; ++hkitr){
(hkitr->second)(this);
}
}
return 0;
}
}
/* vim: set ts=4 sw=4 sts=4 tw=100 */
/***************************************************************************
*
* Copyright (c) 2008 Baidu.com, Inc. All Rights Reserved
* $Id: CmdOption.h,v 1.6 2010/04/13 09:59:41 scmpf Exp $
*
**************************************************************************/
/**
* @file CmdOption.h
* @author yingxiang(com@baidu.com)
* @date 2008/12/29 21:47:53
* @version $Revision: 1.6 $
* @brief
*
**/
#ifndef __CMDOPTION_H_
#define __CMDOPTION_H_
#include "ConfigGroup.h"
#include "utils/cc_utils.h"
namespace comcfg{
/**
* @brief 与getopt行为不一致的地方:
* 如果optstring = "a:b:"
* 当:./run -a -b c d
* optstring会把 -b作为-a的参数
* 而CmdOption会把c, d堆栈处理,把c给-b,把d给-a
*
*/
class CmdOption : public ConfigGroup{
public:
/**
* @brief 命令行参数初始化(不可以重复调用)
*
* @param [in] argc : int 参数个数
* @param [in] argv : char* const* 参数
* @param [in] optstring : const char* 选项信息,与getopt相同
* @return int 0为成功,其它为失败
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:47:13
**/
int init(int argc, char * const * argv, const char * optstring);
/**
* @brief 命令行参数中是否存在某个选项
*
* @return bool
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:48:08
**/
bool hasOption(const char *) const;
/**
* @brief 末尾参数个数(注意:不是总的参数个数)
* 如:argc = 5, argv = {"./run", "-a", "xxx", "-h", "yyy", "zzz"}, optstring = "a:h"
* 那么这里的argSize = 3 (分别是./run, yyy和zzz),其中xxx是-a的参数
*
* @return size_t 参数个数
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:49:16
**/
size_t argSize() const;
/**
* @brief 获取第n个参数
*
* @param [in] n : int 参数位置(0 ~ argSize-1)
* @return const char*
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:51:34
**/
const char * getArg(int n) const;
typedef int (*hook_t)(CmdOption * );
/**
* @brief 注册参数钩子,如果存在option参数,runHook时就执行相应的钩子
* 一个option可注册多个钩子
*
* @param [in] option : const char*
* @param [in] hook : hook_t
* @return int
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:52:09
**/
int registHook(const char * option, hook_t hook);
/**
* @brief 运行钩子
*
* @return int 无意义(runHook不管钩子的运行结果)
* 如关心钩子的运行结果,请在钩子中以异常抛出,自行处理
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:52:53
**/
int runHook();
virtual ConfigUnit & operator= (ConfigUnit & unit) {
return ConfigUnit::operator=(unit);
}
CmdOption();
protected:
static const int CHAR_TABLE_SIZE = 256;
char ch[CHAR_TABLE_SIZE];
static const char CMD_NONE = 0;
static const char CMD_OPT0 = 1;
static const char CMD_OPT1 = 2;
static const char CMD_OPT2 = 3;
std::vector <str_t> arg;
std::multimap <str_t, hook_t> hkmap;
typedef std::pair<str_t, hook_t> pair_t;
typedef std::multimap<str_t, hook_t> :: iterator hkitr_t;
typedef std::pair<hkitr_t, hkitr_t> hk_pair_t;
int setOptString(const char *);
};
}
#endif //__CMDOPTION_H_
/* vim: set ts=4 sw=4 sts=4 tw=100 */
/***************************************************************************
*
* Copyright (c) 2008 Baidu.com, Inc. All Rights Reserved
* $Id: ConfigArray.h,v 1.11 2010/04/13 09:59:41 scmpf Exp $
*
**************************************************************************/
/**
* @file ConfigArray.h
* @author yingxiang(com@baidu.com)
* @date 2008/12/24 10:49:08
* @version $Revision: 1.11 $
* @brief
*
**/
#ifndef __CONFIGARRAY_H_
#define __CONFIGARRAY_H_
#include "ConfigGroup.h"
#include "bsl/var/Array.h"
namespace comcfg{
class ConfigArray : public ConfigGroup{
public:
virtual int push(str_t key, ConfigUnit* unit){
LOG(INFO) << "[" << getFather() << "]ConfigArray[" << this << "] [" << key.c_str() << "].push";
vec.push_back(unit);
return 0;
}
ConfigArray(const char * __name, ConfigGroup * __father=NULL){
if(*__name == '@'){
++__name;
}
create(__name, __father);
}
virtual int selfType() const{
return CONFIG_ARRAY_TYPE;
}
virtual bsl::var::IVar& to_IVar(bsl::ResourcePool * vpool, ErrCode* errCode = NULL)const{
if(vpool == NULL){
LOG(INFO) << "Configure: visit ConfigArray.to_IVar() failed : NULLBUFFER";
setErrorKeyPath(this->_name);
popError(errCode, NULLBUFFER);
return bsl::var::Null::null;
}
bsl::var::Array &arr = vpool->create<bsl::var::Array>();
for(int i = 0; i < (int)vec.size(); ++i){
arr.set( i, vec[i]->to_IVar(vpool, errCode) );
}
return arr;
}
void print(int indent = 0) const{
pindent(indent);
printf("Array--------[%s] : {\n", getName());
for(int i = 0; i < (int)vec.size(); ++i){
vec[i]->print(indent+1);
}
pindent(indent);
printf("}\n");
}
const ConfigUnit & operator[] (int idx) const{
if(idx < (int)vec.size()){
return *vec[idx];
}
LOG(INFO) << "Configure: visit element not exist ConfigArray[int] : " << _name.c_str() << "[" << idx << "]";
str_t tmp=this->_name;
char tmpid[64];
snprintf(tmpid,64, "%d",idx);
tmp.append("[").append(tmpid).append("]");
setErrorKeyPath(tmp);
return *get_err_unit();
}
const ConfigUnit & operator[] (const char *str) const {
LOG(INFO) << "Configure: visit ConfigArray[char *] : " << _name.c_str() << "[" << str << "]";
str_t tmp=this->_name;
tmp.append(".").append(str);
setErrorKeyPath(tmp);
return *get_err_unit();
}
const ConfigUnit & operator[] (const str_t &str) const{
LOG(INFO) << "Configure: visit ConfigArray[str_t] : " << _name.c_str() << "[" << str.c_str() << "]";
str_t tmp=this->_name;
tmp.append(".").append(str);
setErrorKeyPath(tmp);
return *get_err_unit();
}
ConfigUnit & operator[] (int idx) {
if(idx < (int)vec.size()){
return *vec[idx];
}
LOG(INFO) << "Configure: visit element not exist ConfigArray[int] : " << _name.c_str() << "[" << idx << "]";
str_t tmp=this->_name;
char tmpid[64];
snprintf(tmpid,64, "%d",idx);
tmp.append("[").append(tmpid).append("]");
setErrorKeyPath(tmp);
return *get_err_unit();
}
ConfigUnit & operator[] (const char *str) {
LOG(INFO) << "Configure: visit ConfigArray[char *] : " << _name.c_str() << "[" << str << "]";
str_t tmp=this->_name;
tmp.append(".").append(str);
setErrorKeyPath(tmp);
return *get_err_unit();
}
ConfigUnit & operator[] (const str_t &str) {
LOG(INFO) << "Configure: visit ConfigArray[str_t] : " << _name.c_str() << "[" << str.c_str() << "]";
str_t tmp=this->_name;
tmp.append(".").append(str);
setErrorKeyPath(tmp);
return *get_err_unit();
}
virtual ConfigUnit & operator= (ConfigUnit & unit) {
return ConfigUnit::operator=(unit);
}
virtual ~ConfigArray(){
for(int i = 0; i < (int)vec.size(); ++i){
delete vec[i];
}
}
virtual size_t size()const{
return vec.size();
}
const ConfigUnit & get_sub_unit(int index) const {
if ((0<=index) && (index < (int)vec.size())){
return *vec[index];
}
return *get_err_unit();
}
/**
* @brief 比较是否相等
*
* @return int 0表示相等 -1不相等
* @author zhang_rui
**/
virtual int equals(const ConfigUnit & conf) const {
try {
for(int i = 0; i < (int)vec.size(); ++i){
if (0 != vec[i]->equals(conf[i])) {
return -1;
}
}
return 0;
} catch (bsl::Exception) {
return -1;
}
return -1;
}
/**
* @brief 增加一个unit
*
* @return int 0 成功,其他是错误号
* @author zhang_rui
**/
virtual int add_unit(const bsl_string & key, const bsl_string& value,
const int objtype, int except, ConfigUnit ** ref){
ConfigUnit * tmp=NULL;
if (0 < vec.size() && objtype != vec[0]->selfType()) {
goto adderr;
}
tmp = create_unit(key, value, objtype, this->getFather());
if (NULL == tmp){
goto adderr;
}
this->push(key,tmp);
if (NULL != ref) {
*ref = tmp;
}
return 0;
adderr:
if (except) {
popError(NULL, CONFIG_ERROR);
}
return CONFIG_ERROR;
}
/**
* @brief 删除一个unit
*
* @return int 0 成功,其他是错误号
* @author zhang_rui
**/
virtual int del_unit(const bsl_string & key, int except) {
long long val;
int ret = Trans :: str2int64(key, &val);
long long sz = vec.size();
if (0 == ret && 0 <= val && sz > val) {
ConfigUnit * delu = NULL;
std::vector <ConfigUnit *> :: iterator iter;
iter = vec.begin();
iter += val;
delu = *iter;
vec.erase(iter);
if (delu) {
delete delu;
}
return 0;
} else {
if (except) {
if (0 != ul_seterrbuf("%s", "")) {
LOG(WARNING) << "Configure: failed to write error buffer";
}
popError(NULL, NOSUCHKEY);
}
return NOSUCHKEY;
}
return 0;
}
protected:
std::vector <ConfigUnit *> vec;
/**
* @brief 清除内容
*
* @return void
* @author zhang_rui
**/
virtual void clear() {
for(int i = 0; i < (int)vec.size(); ++i){
delete vec[i];
}
vec.clear();
}
};
}
#endif //__CONFIGARRAY_H_
/* vim: set ts=4 sw=4 sts=4 tw=100 */
/***************************************************************************
*
* Copyright (c) 2008 Baidu.com, Inc. All Rights Reserved
* $Id: ConfigError.cpp,v 1.9 2010/04/13 09:59:41 scmpf Exp $
*
**************************************************************************/
/**
* @file ConfigError.cpp
* @author yingxiang(com@baidu.com)
* @date 2008/12/24 14:22:03
* @version $Revision: 1.9 $
* @brief
*
**/
#include "ConfigError.h"
namespace comcfg{
char ConfigError :: to_char(ErrCode * errCode)const{
popError(errCode, NOSUCHKEY);
return char();
}
unsigned char ConfigError :: to_uchar(ErrCode * errCode)const{
popError(errCode, NOSUCHKEY);
return (unsigned char)(0);
}
int16_t ConfigError :: to_int16(ErrCode * errCode)const{
popError(errCode, NOSUCHKEY);
return int16_t();
}
u_int16_t ConfigError :: to_uint16(ErrCode * errCode)const{
popError(errCode, NOSUCHKEY);
return u_int16_t();
}
int ConfigError :: to_int32(ErrCode * errCode)const{
popError(errCode, NOSUCHKEY);
return int();
}
u_int32_t ConfigError :: to_uint32(ErrCode * errCode)const{
popError(errCode, NOSUCHKEY);
return u_int32_t();
}
long long ConfigError :: to_int64(ErrCode * errCode)const{
popError(errCode, NOSUCHKEY);
return (long long)(0);
}
unsigned long long ConfigError :: to_uint64(ErrCode * errCode)const{
popError(errCode, NOSUCHKEY);
return (unsigned long long)(0);
}
float ConfigError :: to_float(ErrCode * errCode)const{
popError(errCode, NOSUCHKEY);
return float();
}
double ConfigError :: to_double(ErrCode * errCode)const{
popError(errCode, NOSUCHKEY);
return double();
}
#if 1
bsl_string ConfigError :: to_bsl_string(ErrCode * errCode)const{
popError(errCode, NOSUCHKEY);
return bsl_string();
}
#endif
#if 0
std_string ConfigError :: to_std_string(ErrCode * errCode)const{
popError(errCode, NOSUCHKEY);
return std_string();
}
#endif
str_t ConfigError :: to_raw_string(ErrCode * errCode)const{
popError(errCode, NOSUCHKEY);
return str_t();
}
const char * ConfigError :: to_cstr(ErrCode * errCode)const{
popError(errCode, NOSUCHKEY);
return NULL;
}
//----------------to_xxx with default value
char ConfigError :: to_char(ErrCode * errCode, const char & def)const {
if(errCode){
*errCode = NOSUCHKEY;
}
return def;
}
unsigned char ConfigError :: to_uchar(ErrCode * errCode, const unsigned char & def)const{
if(errCode){
*errCode = NOSUCHKEY;
}
return def;
}
int16_t ConfigError :: to_int16(ErrCode * errCode, const int16_t & def)const{
if(errCode){
*errCode = NOSUCHKEY;
}
return def;
}
u_int16_t ConfigError :: to_uint16(ErrCode * errCode, const u_int16_t & def)const{
if(errCode){
*errCode = NOSUCHKEY;
}
return def;
}
int ConfigError :: to_int32(ErrCode * errCode, const int & def)const{
if(errCode){
*errCode = NOSUCHKEY;
}
return def;
}
u_int32_t ConfigError :: to_uint32(ErrCode * errCode, const u_int32_t & def)const{
if(errCode){
*errCode = NOSUCHKEY;
}
return def;
}
long long ConfigError :: to_int64(ErrCode * errCode, const long long & def)const{
if(errCode){
*errCode = NOSUCHKEY;
}
return def;
}
unsigned long long ConfigError :: to_uint64(ErrCode * errCode, const unsigned long long & def)const{
if(errCode){
*errCode = NOSUCHKEY;
}
return def;
}
float ConfigError :: to_float(ErrCode * errCode, const float & def)const{
if(errCode){
*errCode = NOSUCHKEY;
}
return def;
}
double ConfigError :: to_double(ErrCode * errCode, const double & def)const{
if(errCode){
*errCode = NOSUCHKEY;
}
return def;
}
bsl_string ConfigError :: to_bsl_string(ErrCode * errCode, const bsl_string & def)const{
if(errCode){
*errCode = NOSUCHKEY;
}
return def;
}
str_t ConfigError :: to_raw_string(ErrCode * errCode, const str_t & def)const{
if(errCode){
*errCode = NOSUCHKEY;
}
return def;
}
//获取C风格的字符串(常量)
const char * ConfigError :: to_cstr(ErrCode * errCode, const char * def)const{
if(errCode){
*errCode = NOSUCHKEY;
}
return def;
}
ErrCode ConfigError :: get_char(char * /*valueBuf*/)const{
return NOSUCHKEY;
}
ErrCode ConfigError :: get_uchar(unsigned char * /*valueBuf*/)const{
return NOSUCHKEY;
}
ErrCode ConfigError :: get_int16(int16_t * /*valueBuf*/)const{
return NOSUCHKEY;
}
ErrCode ConfigError :: get_uint16(u_int16_t * /*valueBuf*/)const{
return NOSUCHKEY;
}
ErrCode ConfigError :: get_int32(int * /*valueBuf*/)const{
return NOSUCHKEY;
}
ErrCode ConfigError :: get_uint32(u_int32_t * /*valueBuf*/)const{
return NOSUCHKEY;
}
ErrCode ConfigError :: get_int64(long long * /*valueBuf*/)const{
return NOSUCHKEY;
}
ErrCode ConfigError :: get_uint64(unsigned long long * /*valueBuf*/)const{
return NOSUCHKEY;
}
ErrCode ConfigError :: get_float(float * /*valueBuf*/)const{
return NOSUCHKEY;
}
ErrCode ConfigError :: get_double(double * /*valueBuf*/)const{
return NOSUCHKEY;
}
#if 1
ErrCode ConfigError :: get_bsl_string(bsl_string * /*valueBuf*/)const{
return NOSUCHKEY;
}
#endif
#if 0
ErrCode ConfigError :: get_std_string(std_string * /*valueBuf*/)const{
return NOSUCHKEY;
}
#endif
ErrCode ConfigError :: get_raw_string(str_t * /*valueBuf*/)const{
return NOSUCHKEY;
}
ErrCode ConfigError :: get_cstr(char * /*valueBuf*/, size_t /*len*/)const{
return NOSUCHKEY;
}
//--------------get_xx with default-----------
ErrCode ConfigError :: get_char(char * valueBuf, const char & def)const{
if (valueBuf) {
*valueBuf = def;
}
return NOSUCHKEY;
}
ErrCode ConfigError :: get_uchar(unsigned char * valueBuf, const unsigned char & def)const{
if (valueBuf) {
*valueBuf = def;
}
return NOSUCHKEY;
}
ErrCode ConfigError :: get_int16(int16_t * valueBuf, const int16_t & def)const{
if (valueBuf) {
*valueBuf = def;
}
return NOSUCHKEY;
}
ErrCode ConfigError :: get_uint16(u_int16_t * valueBuf, const u_int16_t & def)const{
if (valueBuf) {
*valueBuf = def;
}
return NOSUCHKEY;
}
ErrCode ConfigError :: get_int32(int * valueBuf, const int & def)const{
if (valueBuf) {
*valueBuf = def;
}
return NOSUCHKEY;
}
ErrCode ConfigError :: get_uint32(u_int32_t * valueBuf, const u_int32_t & def)const{
if (valueBuf) {
*valueBuf = def;
}
return NOSUCHKEY;
}
ErrCode ConfigError :: get_int64(long long * valueBuf, const long long & def)const{
if (valueBuf) {
*valueBuf = def;
}
return NOSUCHKEY;
}
ErrCode ConfigError :: get_uint64(unsigned long long * valueBuf, const unsigned long long & def)const{
if (valueBuf) {
*valueBuf = def;
}
return NOSUCHKEY;
}
ErrCode ConfigError :: get_float(float * valueBuf, const float & def)const{
if (valueBuf) {
*valueBuf = def;
}
return NOSUCHKEY;
}
ErrCode ConfigError :: get_double(double * valueBuf, const double & def)const{
if (valueBuf) {
*valueBuf = def;
}
return NOSUCHKEY;
}
ErrCode ConfigError :: get_bsl_string(bsl_string * valueBuf, const bsl_string & def)const{
if (valueBuf) {
*valueBuf = def;
}
return NOSUCHKEY;
}
ErrCode ConfigError :: get_raw_string(str_t * valueBuf, const str_t & def)const{
if (valueBuf) {
*valueBuf = def;
}
return NOSUCHKEY;
}
ErrCode ConfigError :: get_cstr(char * valueBuf, size_t len, const char * def)const{
if (valueBuf) {
snprintf(valueBuf, len, "%s", def);
}
return NOSUCHKEY;
}
bsl::var::IVar& ConfigError :: to_IVar(bsl::ResourcePool * /*vpool*/, ErrCode* errCode)const{
popError(errCode, NOSUCHKEY);
return bsl::var::Null::null;
}
int ConfigError :: equals(const ConfigUnit & conf) const {
if (CONFIG_ERROR_TYPE == conf.selfType()) {
return 0;
} else {
return -1;
}
return -1;
}
int ConfigError :: set_value(const bsl_string & /*value*/, int except){
if (except) {
if (0 != ul_seterrbuf("%s", "")) {
LOG(WARNING) << "ConfigUnit: failed to write error buffer";
}
popError(NULL, NOSUCHKEY);
}
return NOSUCHKEY;
}
int ConfigError :: copy_unit(const ConfigUnit & /*unit*/, int except) {
if (except) {
popError(NULL, NOSUCHKEY);
}
return ERROR;
}
}
/* vim: set ts=4 sw=4 sts=4 tw=100 */
/***************************************************************************
*
* Copyright (c) 2008 Baidu.com, Inc. All Rights Reserved
* $Id: ConfigError.h,v 1.11 2010/04/13 09:59:41 scmpf Exp $
*
**************************************************************************/
/**
* @file ConfigUnit.h
* @author yingxiang(com@baidu.com)
* @date 2008/11/26 20:53:09
* @version $Revision: 1.11 $
* @brief
*
**/
#ifndef __CONFIGERROR_H_
#define __CONFIGERROR_H_
#include "utils/cc_utils.h"
#include "ConfigUnit.h"
namespace comcfg{
class ConfigError : public ConfigUnit{
public:
virtual ~ConfigError(){};
virtual char to_char(ErrCode * errCode = NULL)const;
virtual unsigned char to_uchar(ErrCode * errCode = NULL)const;
virtual int16_t to_int16(ErrCode * errCode = NULL)const;
virtual u_int16_t to_uint16(ErrCode * errCode = NULL)const;
virtual int to_int32(ErrCode * errCode = NULL)const;
virtual u_int32_t to_uint32(ErrCode * errCode = NULL)const;
virtual long long to_int64(ErrCode * errCode = NULL)const;
virtual unsigned long long to_uint64(ErrCode * errCode = NULL)const;
virtual float to_float(ErrCode * errCode = NULL)const;
virtual double to_double(ErrCode * errCode = NULL)const;
virtual bsl_string to_bsl_string(ErrCode * errCode = NULL)const;
//virtual std_string to_std_string(ErrCode * errCode = NULL)const;
virtual str_t to_raw_string(ErrCode * errCode = NULL)const;
virtual const char * to_cstr(ErrCode * errCode = NULL)const;
/**
* @brief 带有默认值的to_XXX系列函数
* 返回值与to_xxx系列完全相同。
* 唯一的不同是:当errCode不为0(即发生错误), 返回def默认值
*
* @param [out] errCode : ErrCode* 出错信息
* @param [in] def : const & 默认值
* @return
**/
virtual char to_char(ErrCode * errCode, const char & def)const;
virtual unsigned char to_uchar(ErrCode * errCode, const unsigned char & def)const;
virtual int16_t to_int16(ErrCode * errCode, const int16_t & def)const;
virtual u_int16_t to_uint16(ErrCode * errCode, const u_int16_t & def)const;
virtual int to_int32(ErrCode * errCode, const int & def)const;
virtual u_int32_t to_uint32(ErrCode * errCode, const u_int32_t & def)const;
virtual long long to_int64(ErrCode * errCode, const long long & def)const;
virtual unsigned long long to_uint64(ErrCode * errCode, const unsigned long long & def)const;
virtual float to_float(ErrCode * errCode, const float & def)const;
virtual double to_double(ErrCode * errCode, const double & def)const;
virtual bsl_string to_bsl_string(ErrCode * errCode, const bsl_string & def)const;
virtual str_t to_raw_string(ErrCode * errCode, const str_t & def)const;
//获取C风格的字符串(常量)
virtual const char * to_cstr(ErrCode * errCode, const char * def)const;
virtual ErrCode get_char(char * valueBuf)const;
virtual ErrCode get_uchar(unsigned char * valueBuf)const;
virtual ErrCode get_int16(int16_t * valueBuf)const;
virtual ErrCode get_uint16(u_int16_t * valueBuf)const;
virtual ErrCode get_int32(int * valueBuf)const;
virtual ErrCode get_uint32(u_int32_t * valueBuf)const;
virtual ErrCode get_int64(long long * valueBuf)const;
virtual ErrCode get_uint64(unsigned long long * valueBuf)const;
virtual ErrCode get_float(float * valueBuf)const;
virtual ErrCode get_double(double * valueBuf)const;
virtual ErrCode get_bsl_string(bsl_string * valueBuf)const;
//virtual ErrCode get_std_string(std_string * valueBuf)const;
virtual ErrCode get_raw_string(str_t * valueBuf) const;
virtual ErrCode get_cstr(char * valueBuf, size_t len) const;
/**
* @brief 带有默认值的ge_XXX系列函数
* 返回值与get_xxx系列完全相同。
* 唯一的不同是:当返回值不为0(即发生错误)valueBuf中使用def默认值
*
* @param [out] valueBuf : char* 传出的值
* @param [in] def : const char& 默认值
* @return ErrCode
* @retval
* @see
**/
virtual ErrCode get_char(char * valueBuf, const char & def)const;
virtual ErrCode get_uchar(unsigned char * valueBuf, const unsigned char & def)const;
virtual ErrCode get_int16(int16_t * valueBuf, const int16_t & def)const;
virtual ErrCode get_uint16(u_int16_t * valueBuf, const u_int16_t & def)const;
virtual ErrCode get_int32(int * valueBuf, const int & def)const;
virtual ErrCode get_uint32(u_int32_t * valueBuf, const u_int32_t & def)const;
virtual ErrCode get_int64(long long * valueBuf, const long long & def)const;
virtual ErrCode get_uint64(unsigned long long * valueBuf, const unsigned long long & def)const;
virtual ErrCode get_float(float * valueBuf, const float & def)const;
virtual ErrCode get_double(double * valueBuf, const double & def)const;
virtual ErrCode get_bsl_string(bsl_string * valueBuf, const bsl_string & def)const;
virtual ErrCode get_raw_string(str_t * valueBuf, const str_t & def)const;
virtual ErrCode get_cstr(char * valueBuf, size_t len, const char * def)const;
virtual bsl::var::IVar& to_IVar(bsl::ResourcePool* vpool, ErrCode* errCode = NULL)const;
virtual int selfType() const{
return CONFIG_ERROR_TYPE;
}
virtual size_t size()const{
return 0;
}
virtual str_t info() const{
return str_t("[Error: No such key.]");
}
/**
* @brief 比较是否相等
*
* @return int 0表示相等 -1不相等
* @author zhang_rui
**/
virtual int equals(const ConfigUnit & conf) const;
/**
* @brief 删除一个unit
*
* @return int 0 成功,其他是错误号
* @author zhang_rui
**/
virtual int set_value(const bsl_string & value, int except=0);
/**
* @brief 复制一个unit, 深拷贝
*
* 将unit的内容复制到本对象。
* 类型需要匹配,只能从group复制到group,array复制到array
* @return int 0 成功,其他是错误号
* @author zhang_rui
**/
virtual int copy_unit(const ConfigUnit & unit, int except=0);
virtual ConfigUnit & operator= (ConfigUnit & unit){
return ConfigUnit::operator=(unit);
}
protected:
//str_t key;
//str_t value;
};
}
#endif //__CONFIGERROR_H_
/* vim: set ts=4 sw=4 sts=4 tw=100 */
此差异已折叠。
/***************************************************************************
*
* Copyright (c) 2008 Baidu.com, Inc. All Rights Reserved
* $Id: ConfigGroup.h,v 1.11 2010/04/13 09:59:41 scmpf Exp $
*
**************************************************************************/
/**
* @file ConfigGroup.h
* @author yingxiang(com@baidu.com)
* @date 2008/11/26 21:01:39
* @version $Revision: 1.11 $
* @brief
*
**/
#ifndef __CONFIGGROUP_H_
#define __CONFIGGROUP_H_
#include "ConfigUnit.h"
#include "ConfigError.h"
#include "vector"
namespace comcfg{
enum{
GROUP_DUP_LEVEL0 = 0, //允许重名,不检测
GROUP_DUP_LEVEL1, //检测第一级group,即 "GLOBAL"下的group是否重名
GROUP_DUP_LEVEL2, //检测所有深度的重名group
GROUP_DUP_LEVEL3, //报告所有group名
};
//class ConfigError;
class ConfigGroup : public ConfigError{
public:
ConfigGroup(){
_name = "";
_father = NULL;
fieldMap.create(256);
_dupLevel = GROUP_DUP_LEVEL0;
}
ConfigGroup(const char * __name, ConfigGroup * __father = NULL){
_dupLevel = GROUP_DUP_LEVEL0;
create(__name, __father);
}
virtual const ConfigUnit & operator[] (const char *) const;
virtual const ConfigUnit & operator[] (const str_t &) const;
virtual const ConfigUnit & operator[] (int idx) const;
virtual ConfigUnit & operator[] (const char *) ;
virtual ConfigUnit & operator[] (const str_t &) ;
virtual ConfigUnit & operator[] (int idx) ;
virtual ConfigUnit & operator= (ConfigUnit & unit){
return ConfigUnit::operator=(unit);
}
virtual bsl::var::IVar& to_IVar(bsl::ResourcePool * vpool, ErrCode* errCode = NULL)const;
virtual void print(int indent = 0) const;
virtual ~ConfigGroup();
virtual size_t size()const{
return fieldMap.size();
}
virtual char to_char(ErrCode * errCode = NULL)const;
virtual unsigned char to_uchar(ErrCode * errCode = NULL)const;
virtual int16_t to_int16(ErrCode * errCode = NULL)const;
virtual u_int16_t to_uint16(ErrCode * errCode = NULL)const;
virtual int to_int32(ErrCode * errCode = NULL)const;
virtual u_int32_t to_uint32(ErrCode * errCode = NULL)const;
virtual long long to_int64(ErrCode * errCode = NULL)const;
virtual unsigned long long to_uint64(ErrCode * errCode = NULL)const;
virtual float to_float(ErrCode * errCode = NULL)const;
virtual double to_double(ErrCode * errCode = NULL)const;
virtual bsl_string to_bsl_string(ErrCode * errCode = NULL)const;
virtual str_t to_raw_string(ErrCode * errCode = NULL)const;
virtual const char * to_cstr(ErrCode * errCode = NULL)const;
/**
* @brief 带有默认值的to_XXX系列函数
* 返回值与to_xxx系列完全相同。
* 唯一的不同是:当errCode不为0(即发生错误), 返回def默认值
*
* @param [out] errCode : ErrCode* 出错信息
* @param [in] def : const & 默认值
* @return
**/
virtual char to_char(ErrCode * errCode, const char & def)const;
virtual unsigned char to_uchar(ErrCode * errCode, const unsigned char & def)const;
virtual int16_t to_int16(ErrCode * errCode, const int16_t & def)const;
virtual u_int16_t to_uint16(ErrCode * errCode, const u_int16_t & def)const;
virtual int to_int32(ErrCode * errCode, const int & def)const;
virtual u_int32_t to_uint32(ErrCode * errCode, const u_int32_t & def)const;
virtual long long to_int64(ErrCode * errCode, const long long & def)const;
virtual unsigned long long to_uint64(ErrCode * errCode, const unsigned long long & def)const;
virtual float to_float(ErrCode * errCode, const float & def)const;
virtual double to_double(ErrCode * errCode, const double & def)const;
virtual bsl_string to_bsl_string(ErrCode * errCode, const bsl_string & def)const;
virtual str_t to_raw_string(ErrCode * errCode, const str_t & def)const;
//获取C风格的字符串(常量)
virtual const char * to_cstr(ErrCode * errCode, const char * def)const;
virtual ErrCode get_char(char * valueBuf)const;
virtual ErrCode get_uchar(unsigned char * valueBuf)const;
virtual ErrCode get_int16(int16_t * valueBuf)const;
virtual ErrCode get_uint16(u_int16_t * valueBuf)const;
virtual ErrCode get_int32(int * valueBuf)const;
virtual ErrCode get_uint32(u_int32_t * valueBuf)const;
virtual ErrCode get_int64(long long * valueBuf)const;
virtual ErrCode get_uint64(unsigned long long * valueBuf)const;
virtual ErrCode get_float(float * valueBuf)const;
virtual ErrCode get_double(double * valueBuf)const;
virtual ErrCode get_bsl_string(bsl_string * valueBuf)const;
virtual ErrCode get_raw_string(str_t * valueBuf) const;
virtual ErrCode get_cstr(char * valueBuf, size_t len) const;
/**
* @brief 带有默认值的ge_XXX系列函数
* 返回值与get_xxx系列完全相同。
* 唯一的不同是:当返回值不为0(即发生错误)valueBuf中使用def默认值
*
* @param [out] valueBuf : char* 传出的值
* @param [in] def : const char& 默认值
* @return ErrCode
* @retval
* @see
**/
virtual ErrCode get_char(char * valueBuf, const char & def)const;
virtual ErrCode get_uchar(unsigned char * valueBuf, const unsigned char & def)const;
virtual ErrCode get_int16(int16_t * valueBuf, const int16_t & def)const;
virtual ErrCode get_uint16(u_int16_t * valueBuf, const u_int16_t & def)const;
virtual ErrCode get_int32(int * valueBuf, const int & def)const;
virtual ErrCode get_uint32(u_int32_t * valueBuf, const u_int32_t & def)const;
virtual ErrCode get_int64(long long * valueBuf, const long long & def)const;
virtual ErrCode get_uint64(unsigned long long * valueBuf, const unsigned long long & def)const;
virtual ErrCode get_float(float * valueBuf, const float & def)const;
virtual ErrCode get_double(double * valueBuf, const double & def)const;
virtual ErrCode get_bsl_string(bsl_string * valueBuf, const bsl_string & def)const;
virtual ErrCode get_raw_string(str_t * valueBuf, const str_t & def)const;
virtual ErrCode get_cstr(char * valueBuf, size_t len, const char * def)const;
virtual const ConfigUnit & get_sub_unit(int index) const;
inline virtual const bsl::string & get_key_name() const{
return this->_name;
}
/**
* @brief 比较是否相等
*
* @return int 0表示相等 -1不相等
* @author zhang_rui
**/
virtual int equals(const ConfigUnit & conf) const;
/**
* @brief 增加一个子unit
*
* @return int 0 成功,其他是错误号
* @author zhang_rui
**/
virtual int add_unit(const bsl_string & key, const bsl_string& value,
const int objtype=CONFIG_UNIT_TYPE,int except=0, ConfigUnit ** ref=NULL);
/**
* @brief 删除一个unit
*
* @return int 0 成功,其他是错误号
* @author zhang_rui
**/
virtual int del_unit(const bsl_string & key, int except=0);
/**
* @brief 复制一个unit, 深拷贝
*
* 将unit的内容复制到本对象。
* 类型需要匹配,只能从group复制到group,array复制到array
* @return int 0 成功,其他是错误号
* @author zhang_rui
**/
virtual int copy_unit(const ConfigUnit & unit, int except=0);
protected:
friend class Reader;
friend class Constraint;
friend class Configure;
friend class ConfigUnit;
friend class CFdefault;
void create(const char * __name, ConfigGroup * __father = NULL);
ConfigUnit * relativeSection(ConfigUnit *globalSec, str_t str, int * depth);
int push(const str_t& key, ConfigUnit* unit);
const char * getName() const{
return _name.c_str();
}
virtual int selfType() const{
return CONFIG_GROUP_TYPE;
}
int getLevel() const{
return _level;
}
int _level;
//ConfigGroup * _father;
str_t _name;
std::vector <str_t > fieldList;
typedef bsl::hashmap <str_t, ConfigUnit*> :: iterator itr_t;
typedef bsl::hashmap <str_t, ConfigUnit*> :: const_iterator const_itr_t;
typedef bsl::hashmap <str_t, ConfigUnit*> :: _Pair * ptr_t;
bsl::hashmap <str_t, ConfigUnit*> fieldMap;
/**
* @brief 清除内容
*
* @return void
* @author zhang_rui
**/
virtual void clear();
/*
* @brief 根据_dupLevel允许的重名等级打印group名
*
* @return 0,正常;DUPLICATED_GROUP,存在重名的group
在_dupLevel为GROUP_DUP_LEVEL0或GROUP_DUP_LEVEL3时,返回0
* @author Lin_jieqiong
*/
int printGroup();
struct dup_position{
str_t file;
int line;
};
typedef std::vector <struct dup_position> dup_vector;
typedef bsl::hashmap <ConfigUnit *, dup_vector> :: iterator dup_itr;
typedef bsl::hashmap <ConfigUnit *, dup_vector> :: _Pair * dup_ptr;
bsl::hashmap <ConfigUnit *, dup_vector> _dupMap;
int _dupLevel;
public:
/**
* @brief 复制一个group的子unit, 深拷贝
*
* @return int 0 成功,其他是错误号
* @author zhang_rui
**/
virtual int _append_unit(const ConfigUnit & unit,int check=1, int except=0);
};
}
#endif //__CONFIGGROUP_H_
/* vim: set ts=4 sw=4 sts=4 tw=100 */
/***************************************************************************
*
* Copyright (c) 2010 Baidu.com, Inc. All Rights Reserved
*
**************************************************************************/
/**
* @file ConfigReloader.cpp
* @author zhang_rui(com@baidu.com)
* @date 2010-1-21
* @brief
*
**/
#include "ConfigReloader.h"
#include <time.h>
#include <bsl/exception/bsl_exception.h>
static const int hashmap_bitems = 256;
namespace comcfg {
#define COMCFG_SAFEFREE(obj) do {if (NULL != (obj)) { delete (obj); (obj)=NULL; }} while(0)
ConfigReloader :: ConfigReloader() : _finit(0), _last_modify(0) {
_config[0] = 0;
_config[1] = 0;
_config_curid = 0;
_load_param.filename = "";
_load_param.rangename = "";
_load_param.path = "";
_load_param.version = CONFIG_VERSION_1_0;
_chrcbmap.create(hashmap_bitems);
_strcbmap.create(hashmap_bitems);
_intcbmap.create(hashmap_bitems);
_uint64cbmap.create(hashmap_bitems);
_floatcbmap.create(hashmap_bitems);
_groupcbmap.create(hashmap_bitems);
}
/**
* @brief 设定要监控的配置文件
*
* @param [in] path : const char* 配置文件的路径
* @param [in] conf : const char* 配置文件名
* @param [in] range : const char* 约束文件,约束文件不进行更新检查
* @param [in] version : int 文件格式的版本(暂未使用)
* @return int 0表示成功,其余为失败
**/
int ConfigReloader :: init(const char * path, const char * conf,
const char * range, int version) {
if(path == NULL || conf == NULL){
LOG(WARNING) << "ConfigReloader.init : path or filename error...";
return -1;
}
if (_finit) {
LOG(WARNING) << "ConfigReloader.init : already init. Can not init twice.";
return -1;
}
_load_param.filename = conf;
if (NULL != range) {
_load_param.rangename = range;
} else {
_load_param.rangename = "";
}
_load_param.path = path;
_load_param.version = version;
int ret=0;
_config[_config_curid] = new comcfg::Configure;
ret = _config[_config_curid]->load(path, conf,range,version);
if (0 != ret) {
COMCFG_SAFEFREE(_config[_config_curid]);
return ret;
}
_last_modify = _config[_config_curid]->lastConfigModify();
if (0 == _last_modify) {
LOG(WARNING) << "ConfigReloader.init : get last modify time error...";
COMCFG_SAFEFREE(_config[_config_curid]);
return -1;
}
if (0 == ret) {
_finit = 1;
}
return ret;
}
int ConfigReloader :: _add_key_monitor(config_monmap_t * map, const char * key,
key_change_cb_t proc, void * prm) {
if(key == NULL || NULL == proc){
LOG(WARNING) << "ConfigReloader._add_key_monitor : NULL key or callback";
return -1;
}
bsl::string kstr = key;
config_monitor_t * pmon = new config_monitor_t;
pmon->callback = proc;
pmon->param = prm;
config_monmap_pr_t ptr;
ptr = map->find(kstr);
if(NULL != ptr) {
if (NULL != ptr->second) {
delete ptr->second;
}
map->erase(ptr->first);
LOG(WARNING) << "ConfigReloader._add_key_monitor : "
"same key exist, update callback("<< proc << "), param(" << prm << ")";
}
(*map).set(kstr, pmon, 1);
return 0;
}
int ConfigReloader :: reload() {
int nextid = (_config_curid + 1) % 2;
COMCFG_SAFEFREE(_config[nextid]);
_config[nextid] = new comcfg :: Configure;
int ret = _config[nextid]->load(_load_param.path.c_str(), _load_param.filename.c_str(),
_load_param.rangename.c_str(), _load_param.version);
if (0 != ret) {
COMCFG_SAFEFREE(_config[nextid]);
return -1;
}
_config_curid = nextid;
return ret;
}
int ConfigReloader :: check() {
int oldid = (_config_curid + 1) % 2;
try {
int ret = 0;
bsl::hashmap <bsl::string, config_monitor_t *> :: iterator itr;
//先检查合法
for(itr = _chrcbmap.begin(); itr != _chrcbmap.end(); ++itr){
_config[_config_curid]->deepGet(itr->first).to_char();
}
for (itr = _strcbmap.begin(); itr != _strcbmap.end(); ++itr) {
_config[_config_curid]->deepGet(itr->first).to_bsl_string();
}
for (itr = _intcbmap.begin(); itr != _intcbmap.end(); ++itr) {
_config[_config_curid]->deepGet(itr->first).to_int64();
}
for (itr = _uint64cbmap.begin(); itr != _uint64cbmap.end(); ++itr) {
_config[_config_curid]->deepGet(itr->first).to_uint64();
}
for (itr = _floatcbmap.begin(); itr != _floatcbmap.end(); ++itr) {
_config[_config_curid]->deepGet(itr->first).to_double();
}
for (itr = _groupcbmap.begin(); itr != _groupcbmap.end(); ++itr) {
int ty = _config[_config_curid]->deepGet(itr->first).selfType();
if (CONFIG_GROUP_TYPE != ty && CONFIG_ARRAY_TYPE != ty) {
LOG(WARNING) << "ConfigReloader.add_group_monitor :"
" (" << itr->first.c_str() << ") is not group or array";
return -1;
}
}
//再检查数据是否改变
for(itr = _chrcbmap.begin(); itr != _chrcbmap.end(); ++itr){
if (NULL != itr->second) {
config_monitor_t * pmon = (config_monitor_t *) (itr->second);
if (_config[_config_curid]->deepGet(itr->first).to_char() !=
_config[oldid]->deepGet(itr->first).to_char()) {
pmon->callback(_config[oldid]->deepGet(itr->first),
_config[_config_curid]->deepGet(itr->first), pmon->param);
++ret;
}
}
}
for (itr = _strcbmap.begin(); itr != _strcbmap.end(); ++itr) {
if (NULL != itr->second) {
config_monitor_t * pmon = (config_monitor_t *) (itr->second);
if (_config[_config_curid]->deepGet(itr->first).to_bsl_string()
!= _config[oldid]->deepGet(itr->first).to_bsl_string()) {
pmon->callback(_config[oldid]->deepGet(itr->first),
_config[_config_curid]->deepGet(itr->first),
pmon->param);
++ret;
}
}
}
for (itr = _intcbmap.begin(); itr != _intcbmap.end(); ++itr) {
if (NULL != itr->second) {
config_monitor_t * pmon = (config_monitor_t *) (itr->second);
if (_config[_config_curid]->deepGet(itr->first).to_int64()
!= _config[oldid]->deepGet(itr->first).to_int64()) {
pmon->callback(_config[oldid]->deepGet(itr->first),
_config[_config_curid]->deepGet(itr->first),
pmon->param);
++ret;
}
}
}
for (itr = _uint64cbmap.begin(); itr != _uint64cbmap.end(); ++itr) {
if (NULL != itr->second) {
config_monitor_t * pmon = (config_monitor_t *) (itr->second);
if (_config[_config_curid]->deepGet(itr->first).to_uint64()
!= _config[oldid]->deepGet(itr->first).to_uint64()) {
pmon->callback(_config[oldid]->deepGet(itr->first),
_config[_config_curid]->deepGet(itr->first),
pmon->param);
++ret;
}
}
}
for (itr = _floatcbmap.begin(); itr != _floatcbmap.end(); ++itr) {
if (NULL != itr->second) {
config_monitor_t * pmon = (config_monitor_t *) (itr->second);
if (_config[_config_curid]->deepGet(itr->first).to_double()
!= _config[oldid]->deepGet(itr->first).to_double()) {
pmon->callback(_config[oldid]->deepGet(itr->first),
_config[_config_curid]->deepGet(itr->first),
pmon->param);
++ret;
}
}
}
for (itr = _groupcbmap.begin(); itr != _groupcbmap.end(); ++itr) {
if (NULL != itr->second) {
config_monitor_t * pmon = (config_monitor_t *) (itr->second);
if (0 != _config[_config_curid]->deepGet(itr->first)
.equals(_config[oldid]->deepGet(itr->first)) ) {
pmon->callback(_config[oldid]->deepGet(itr->first),
_config[_config_curid]->deepGet(itr->first),
pmon->param);
++ret;
}
}
}
for(int i = 0; i < (int)_filecblist.size(); ++i){
config_monitor_t * pmon = _filecblist[i];
if (NULL != pmon && NULL!= pmon->callback) {
pmon->callback(*(_config[oldid]), *(_config[_config_curid]), pmon->param);
++ret;
}
}
return ret;
} catch (bsl::Exception &e) {
LOG(WARNING) << "ConfigReloader.check : error(" << e.what() << ")";
return -1;
} catch (...) {
LOG(WARNING) << "ConfigReloader.check : unknown error";
return -1;
}
LOG(WARNING) << "ConfigReloader.check : unknown error, the codes lost road.";
return -1;
}
/**
* @brief 检查配置文件是否发生变化。
*
* @return int 0表示配置没有不安化,1表示配置发生了变化并进行了通知,-1表示更新后的配置内容错误或约束错误。
* -2表示其他错误
**/
int ConfigReloader :: monitor() {
if (NULL == _config[_config_curid]) {
LOG(WARNING) << "ConfigReloader.monitor : NULL config(" << _config_curid << "), init failed?";
return -2;
}
time_t modtime = _config[_config_curid]->lastConfigModify();
if (modtime > _last_modify) {
if (0 != reload()) {
LOG(WARNING) << "ConfigReloader.monitor : reload error("<< _load_param.filename.c_str() << ")";
return -1;
}
int ret = check();
if (-1 == ret) {
LOG(WARNING) << "ConfigReloader.monitor : check error(" << _load_param.filename.c_str() << ")";
int oldid = _config_curid;
_config_curid = (_config_curid + 1) % 2;
COMCFG_SAFEFREE(_config[oldid]);
return -2;
}
_last_modify = modtime;
return ret;
} else {
return 0;
}
LOG(WARNING) << "ConfigReloader.monitor : unknown error(" << _load_param.filename.c_str() << ")";
return -2;
}
/**
* @brief 增加要监控的整数key
*
* @param [in] key : const char* 配置项的全路径
* @param [in] proc : key_change_cb_t 处理回调函数
* @return int 0表示成功,-1为失败
**/
int ConfigReloader :: add_key_int(const char * key, key_change_cb_t proc, void * prm) {
try {
if (NULL == key) {
LOG(WARNING) << "ConfigReloader.add_key_int : NULL key.";
return -1;
}
if (NULL == _config[_config_curid]) {
LOG(WARNING) << "ConfigReloader.add_key_int : NULL config. init failed?";
return -1;
}
_config[_config_curid]->deepGet(key).to_int64();
} catch (bsl::Exception &e) {
LOG(WARNING) << "ConfigReloader.add_key_int : error(" << e.what() << ")";
return -1;
} catch (...) {
LOG(WARNING) << "ConfigReloader.add_key_int : unknown error";
return -1;
}
return _add_key_monitor(&_intcbmap, key, proc, prm);
}
/**
* @brief 增加要监控的uint64 key
*
* @param [in] key : const char* 配置项的全路径
* @param [in] proc : key_change_cb_t 处理回调函数
* @return int 0表示成功,-1为失败
**/
int ConfigReloader :: add_key_uint64(const char * key, key_change_cb_t proc, void * prm) {
try {
if (NULL == key) {
LOG(WARNING) << "ConfigReloader.add_key_uint64 : NULL key.";
return -1;
}
if (NULL == _config[_config_curid]) {
LOG(WARNING) << "ConfigReloader.add_key_uint64 : NULL config. init failed?";
return -1;
}
_config[_config_curid]->deepGet(key).to_uint64();
} catch (bsl::Exception &e) {
LOG(WARNING) << "ConfigReloader.add_key_uint64 : error(" << e.what() << ")";
return -1;
} catch (...) {
LOG(WARNING) << "ConfigReloader.add_key_uint64 : unknown error";
return -1;
}
return _add_key_monitor(&_uint64cbmap, key, proc, prm);
}
/**
* @brief 增加要监控的浮点类型key
*
* @param [in] key : const char* 配置项的全路径
* @param [in] proc : key_change_cb_t 处理回调函数
* @return int 0表示成功,-1为失败
**/
int ConfigReloader :: add_key_float(const char * key, key_change_cb_t proc, void * prm) {
try {
if (NULL == key) {
LOG(WARNING) << "ConfigReloader.add_key_float : NULL key.";
return -1;
}
if (NULL == _config[_config_curid]) {
LOG(WARNING) << "ConfigReloader.add_key_float : NULL config. init failed?";
return -1;
}
_config[_config_curid]->deepGet(key).to_double();
} catch (bsl::Exception &e) {
LOG(WARNING) << "ConfigReloader.add_key_float : error(" << e.what() << ")";
return -1;
} catch (...) {
LOG(WARNING) << "ConfigReloader.add_key_float : unknown error";
return -1;
}
return _add_key_monitor(&_floatcbmap, key, proc, prm);
}
/**
* @brief 增加要监控的字符key
*
* @param [in] key : const char* 配置项的全路径
* @param [in] proc : key_change_cb_t 处理回调函数
* @return int 0表示成功,-1为失败
**/
int ConfigReloader :: add_key_char(const char * key, key_change_cb_t proc, void * prm) {
try {
if (NULL == key) {
LOG(WARNING) << "ConfigReloader.add_key_char : NULL key.";
return -1;
}
if (NULL == _config[_config_curid]) {
LOG(WARNING) << "ConfigReloader.add_key_char : NULL config. init failed?";
return -1;
}
_config[_config_curid]->deepGet(key).to_char();
} catch (bsl::Exception &e) {
LOG(WARNING) << "ConfigReloader.add_key_char : error(" << e.what() << ")";
return -1;
} catch (...) {
LOG(WARNING) << "ConfigReloader.add_key_char : unknown error";
return -1;
}
return _add_key_monitor(&_chrcbmap, key, proc, prm);
}
/**
* @brief 增加要监控的字符串key
*
* @param [in] key : const char* 配置项的全路径
* @param [in] proc : key_change_cb_t 处理回调函数
* @return int 0表示成功,-1为失败
**/
int ConfigReloader :: add_key_string(const char * key, key_change_cb_t proc, void * prm) {
try {
if (NULL == key) {
LOG(WARNING) << "ConfigReloader.add_key_string : NULL key.";
return -1;
}
if (NULL == _config[_config_curid]) {
LOG(WARNING) << "ConfigReloader.add_key_string : NULL config. init failed?";
return -1;
}
_config[_config_curid]->deepGet(key).to_bsl_string();
} catch (bsl::Exception &e) {
LOG(WARNING) << "ConfigReloader.add_key_string : error(" << e.what() << ")";
return -1;
} catch (...) {
LOG(WARNING) << "ConfigReloader.add_key_string : unknown error";
return -1;
}
return _add_key_monitor(&_strcbmap, key, proc, prm);
}
/**
* @brief 增加监控[group]的回调
*
* @param [in] group : const char* 配置项的全路径
* @param [in] proc : key_change_cb_t 处理回调函数
* @return int 0表示成功,-1为失败
**/
int ConfigReloader :: add_group_monitor(const char * group, key_change_cb_t proc, void * prm) {
try {
if (NULL == group) {
LOG(WARNING) << "ConfigReloader.add_group_monitor : NULL key.";
return -1;
}
if (NULL == _config[_config_curid]) {
LOG(WARNING) << "ConfigReloader.add_group_monitor : NULL config. init failed?";
return -1;
}
int ty =_config[_config_curid]->deepGet(group).selfType();
if (CONFIG_GROUP_TYPE != ty && CONFIG_ARRAY_TYPE != ty) {
LOG(WARNING) << "ConfigReloader.add_group_monitor :"
" (" << group << ") is not group or array";
return -1;
}
} catch (bsl::Exception &e) {
LOG(WARNING) << "ConfigReloader.add_group_monitor : error(" << e.what() << ")";
return -1;
} catch (...) {
LOG(WARNING) << "ConfigReloader.add_group_monitor : unknown error";
return -1;
}
return _add_key_monitor(&_groupcbmap, group, proc, prm);
}
/**
* @brief 增加监控整个文件的回调
*
* @param [in] proc : key_change_cb_t 处理回调函数
* @return int 0表示成功,-1为失败
**/
int ConfigReloader :: add_file_monitor(key_change_cb_t proc, void * prm) {
if (NULL == _config[_config_curid]) {
LOG(WARNING) << "ConfigReloader.add_file_monitor : NULL config. init failed?";
return -1;
}
if(NULL == proc) {
LOG(WARNING) << "ConfigReloader.add_file_monitor : NULL callback";
return -1;
}
for(int i = 0; i < (int)_filecblist.size(); ++i){
config_monitor_t * pmon = _filecblist[i];
if (NULL != pmon && proc == pmon->callback) {
pmon->param = prm;
LOG(WARNING) << "ConfigReloader.add_file_monitor : "
"same callback exist, updated param to " << prm;
return -1;
}
}
config_monitor_t * pmon = new config_monitor_t;
pmon->callback = proc;
pmon->param = prm;
_filecblist.push_back(pmon);
return 0;
}
Configure * ConfigReloader :: get_config() {
return _config[_config_curid];
}
void ConfigReloader :: _free_map(bsl::hashmap <bsl::string, config_monitor_t *> *map) {
bsl::hashmap<bsl::string, config_monitor_t *>::iterator itr;
for(itr = map->begin(); itr != map->end(); ++itr) {
if (NULL != itr->second) {
delete itr->second;
}
}
if(0 != map->destroy())
LOG(WARNING) << "ConfigReloader._free_map : "
"map->destory() failed ";
}
void ConfigReloader :: _free_list(std::vector <config_monitor_t *> *list) {
for(int i = 0; i < (int)list->size(); ++i){
if (NULL != (*list)[i]) {
delete (*list)[i];
}
}
}
ConfigReloader :: ~ConfigReloader() {
_free_map(&_chrcbmap);
_free_map(&_strcbmap);
_free_map(&_intcbmap);
_free_map(&_uint64cbmap);
_free_map(&_floatcbmap);
_free_map(&_groupcbmap);
_free_list(&_filecblist);
COMCFG_SAFEFREE(_config[0]);
COMCFG_SAFEFREE(_config[1]);
}
}//namespace comcfg
/***************************************************************************
*
* Copyright (c) 2010 Baidu.com, Inc. All Rights Reserved
*
**************************************************************************/
/**
* @file ConfigReloader.h
* @author zhang_rui(com@baidu.com)
* @date 2010-1-21
* @brief
*
**/
#ifndef CONFIGRELOADER_H_
#define CONFIGRELOADER_H_
#include "Configure.h"
namespace comcfg {
typedef int (*key_change_cb_t)(const ConfigUnit &keyold, \
const ConfigUnit &keynew, void * prm); /**< 处理配置项变更的回调函数类型 */
typedef struct _load_param_t {
bsl::string path; /**< 路径 */
bsl::string filename; /**< 配置文件 */
bsl::string rangename; /**< 约束文件 */
int version; /**< 版本 */
}load_param_t ;
typedef struct _config_monitor_t {
key_change_cb_t callback;
void * param;
} config_monitor_t;
class ConfigReloader {
typedef bsl::hashmap <bsl::string, config_monitor_t *> config_monmap_t;
typedef bsl::hashmap <bsl::string, config_monitor_t *> :: iterator config_monmap_itr_t;
typedef bsl::hashmap <bsl::string, config_monitor_t *> :: _Pair* config_monmap_pr_t;
private:
int _finit; /**< 初始化标志 */
load_param_t _load_param; /**< load 参数 */
Configure * _config[2]; /**< configure对象,原文件和更新文件 */
int _config_curid; /**< load 参数 */
time_t _last_modify; /**< 最近修改时间 */
std::vector <config_monitor_t *> _filecblist; /**< 处理文件变更的回调 */
bsl::hashmap <bsl::string, config_monitor_t *> _chrcbmap; /**< 存储监控的字符key和回调 */
bsl::hashmap <bsl::string, config_monitor_t *> _strcbmap; /**< 存储监控的字符串key和回调 */
bsl::hashmap <bsl::string, config_monitor_t *> _intcbmap; /**< 存储监控的整数key和回调 */
bsl::hashmap <bsl::string, config_monitor_t *> _uint64cbmap; /**< 存储监控的浮点key和回调 */
bsl::hashmap <bsl::string, config_monitor_t *> _floatcbmap; /**< 存储监控的浮点key和回调 */
bsl::hashmap <bsl::string, config_monitor_t *> _groupcbmap; /**< 存储监控的group和回调 */
/**
* @brief 增加一个监控回调到map中
*
* @param [in] key : const char* 配置项的全路径
* @param [in] proc : key_change_cb_t 处理回调函数
* @param [in] prm : 参数
* @return int 0表示成功,-1为失败
**/
int _add_key_monitor(config_monmap_t * map, const char * key, key_change_cb_t proc, void * prm);
/**
* @brief 释放存储的数据
*
* @param [in] map : bsl::hashmap
* @return void
**/
void _free_map(bsl::hashmap <bsl::string, config_monitor_t *> *map);
/**
* @brief 释放存储的数据
*
* @param [in] map : bsl::hashmap
* @return void
**/
void _free_list(std::vector <config_monitor_t *> *list);
/**
* @brief 重新载入configure文件
* @return int 0表示成功 其他失败
**/
int reload();
/**
* @brief 检查各个监控值。
* @return int 0表示配置没有检查项,>=1表示配置发生了变化并进行了通知,-1表示错误。
**/
int check();
public :
/**
* @brief 设定要监控的配置文件
*
* @param [in] path : const char* 配置文件的路径
* @param [in] conf : const char* 配置文件名
* @param [in] range : const char* 约束文件,约束文件不进行更新检查
* @param [in] version : int 文件格式的版本(暂未使用)
* @return int 0表示成功,其余为失败
**/
int init(const char * path, const char * conf, const char * range = NULL, int version = CONFIG_VERSION_1_0);
/**
* @brief 检查配置文件是否发生变化。
*
* @return int 0表示配置没有不安化,正数表示配置发生了变化并进行了通知的回调个数,-1表示更新后的配置内容错误或约束错误。
* -2表示其他错误
**/
int monitor();
/**
* @brief 增加要监控的整数key
*
* @param [in] key : const char* 配置项的全路径
* @param [in] proc : key_change_cb_t 处理回调函数
* @return int 0表示成功,-1为失败
**/
int add_key_int(const char * key, key_change_cb_t proc, void * prm);
/**
* @brief 增加要监控的uint64 key
*
* @param [in] key : const char* 配置项的全路径
* @param [in] proc : key_change_cb_t 处理回调函数
* @return int 0表示成功,-1为失败
**/
int add_key_uint64(const char * key, key_change_cb_t proc, void * prm);
/**
* @brief 增加要监控的浮点类型key
*
* @param [in] key : const char* 配置项的全路径
* @param [in] proc : key_change_cb_t 处理回调函数
* @return int 0表示成功,-1为失败
**/
int add_key_float(const char * key, key_change_cb_t proc, void * prm);
/**
* @brief 增加要监控的字符key
*
* @param [in] key : const char* 配置项的全路径
* @param [in] proc : key_change_cb_t 处理回调函数
* @return int 0表示成功,-1为失败
**/
int add_key_char(const char * key, key_change_cb_t proc, void * prm);
/**
* @brief 增加要监控的字符串key
*
* @param [in] key : const char* 配置项的全路径
* @param [in] proc : key_change_cb_t 处理回调函数
* @return int 0表示成功,-1为失败
**/
int add_key_string(const char * key, key_change_cb_t proc, void * prm);
/**
* @brief 增加监控[group]的回调
*
* @param [in] group : const char* 配置项的全路径
* @param [in] proc : key_change_cb_t 处理回调函数
* @return int 0表示成功,-1为失败
**/
int add_group_monitor(const char * group, key_change_cb_t proc, void * prm);
/**
* @brief 增加监控整个文件的回调
*
* @param [in] proc : key_change_cb_t 处理回调函数
* @return int 0表示成功,-1为失败
**/
int add_file_monitor(key_change_cb_t proc, void * prm);
/**
* @brief 获取当前的configure
**/
Configure * get_config();
ConfigReloader();
~ConfigReloader();
};
}//namespace comcfg
#endif /* CONFIGRELOADER_H_ */
此差异已折叠。
/***************************************************************************
*
* Copyright (c) 2008 Baidu.com, Inc. All Rights Reserved
* $Id: ConfigUnit.h,v 1.19 2010/04/13 09:59:41 scmpf Exp $
*
**************************************************************************/
/**
* @file ConfigUnit.h
* @author yingxiang(com@baidu.com)
* @date 2008/11/26 20:53:09
* @version $Revision: 1.19 $
* @brief
*
**/
#ifndef __CONFIGUNIT_H_
#define __CONFIGUNIT_H_
#include "utils/cc_utils.h"
#include "bsl/var/IVar.h"
#include "bsl/var/Ref.h"
#include "bsl/ResourcePool.h"
#include "bsl/containers/hash/bsl_hashmap.h"
#include <vector>
namespace comcfg{
enum{
CONFIG_UNIT_TYPE = 0,
CONFIG_GROUP_TYPE,
CONFIG_ARRAY_TYPE,
CONFIG_ERROR_TYPE
};
class Reader;
class ConfigGroup;
class ConfigUnit{
public:
/**
* @brief 方括号重载(三个函数),支持以方括号获取相应字段
* 支持字符串、bsl::string和int下标。int下标Array专用。
* 如果出错,返回一个ConfigError类型的常量
* 可以用 conf[""].selfType() != CONFIG_ERROR_TYPE来判断
*
* @return const ConfigUnit& []
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:18:13
**/
virtual const ConfigUnit & operator[] (const char *) const;
virtual const ConfigUnit & operator[] (const str_t &) const;
virtual const ConfigUnit & operator[] (int) const;
virtual ConfigUnit & operator[] (const char *) ;
virtual ConfigUnit & operator[] (const str_t &) ;
virtual ConfigUnit & operator[] (int) ;
virtual ConfigUnit & operator= (ConfigUnit & unit) ;
/**
* @brief 将一个ErrCode转化为一个对应的字符串信息
* ErrCode内部就是一个int, 0为OK,非0为出错信息
*
* @return const char*
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:21:07
**/
virtual const char * seeError(const ErrCode &) const;
virtual ~ConfigUnit();
/**
* @brief 从一个字段中获取特定类型的数据
* XXX to_XXX() 表示以XXX类型获取该配置项
*
* @param [out] errCode : ErrCode* 出错信息
* errCode不为NULL时,错误号将会写入*errCode
* 当此处errCode为默认值NULL时,出错将会以异常的形式抛出
* 抛出的异常为:ConfigException或其子类
* @return char
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:22:07
**/
virtual char to_char(ErrCode * errCode = NULL)const;
virtual unsigned char to_uchar(ErrCode * errCode = NULL)const;
virtual int16_t to_int16(ErrCode * errCode = NULL)const;
virtual u_int16_t to_uint16(ErrCode * errCode = NULL)const;
virtual int to_int32(ErrCode * errCode = NULL)const;
virtual u_int32_t to_uint32(ErrCode * errCode = NULL)const;
virtual long long to_int64(ErrCode * errCode = NULL)const;
virtual unsigned long long to_uint64(ErrCode * errCode = NULL)const;
virtual float to_float(ErrCode * errCode = NULL)const;
virtual double to_double(ErrCode * errCode = NULL)const;
virtual bsl_string to_bsl_string(ErrCode * errCode = NULL)const;
//to_std_string : 返回值为std::string,如果是双引号开头的串,这里的字符串是经过转义的,\'\x41\' -> 'A'
//virtual std_string to_std_string(ErrCode * errCode = NULL)const;
//to_raw_string : 未经过转义处理的字符串
virtual str_t to_raw_string(ErrCode * errCode = NULL)const;
//获取C风格的字符串(常量)
virtual const char * to_cstr(ErrCode * errCode = NULL)const;
/**
* @brief 带有默认值的to_XXX系列函数
* 返回值与to_xxx系列完全相同。
* 唯一的不同是:当errCode不为0(即发生错误), 返回def默认值
*
* @param [out] errCode : ErrCode* 出错信息
* @param [in] def : const & 默认值
* @return
* @author zhang_rui
* @date 2009/03/11 22:37:46
**/
virtual char to_char(ErrCode * errCode, const char & def)const;
virtual unsigned char to_uchar(ErrCode * errCode, const unsigned char & def)const;
virtual int16_t to_int16(ErrCode * errCode, const int16_t & def)const;
virtual u_int16_t to_uint16(ErrCode * errCode, const u_int16_t & def)const;
virtual int to_int32(ErrCode * errCode, const int & def)const;
virtual u_int32_t to_uint32(ErrCode * errCode, const u_int32_t & def)const;
virtual long long to_int64(ErrCode * errCode, const long long & def)const;
virtual unsigned long long to_uint64(ErrCode * errCode, const unsigned long long & def)const;
virtual float to_float(ErrCode * errCode, const float & def)const;
virtual double to_double(ErrCode * errCode, const double & def)const;
virtual bsl_string to_bsl_string(ErrCode * errCode, const bsl_string & def)const;
virtual str_t to_raw_string(ErrCode * errCode, const str_t & def)const;
//获取C风格的字符串(常量)
virtual const char * to_cstr(ErrCode * errCode, const char * def)const;
/**
* @brief 与to_XXX功能相同的函数。不过get_XXX系列为C风格
* 传入为用于放值的buffer,返回值是错误号
*
* @param [out] valueBuf : char*
* @return ErrCode
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:25:52
**/
virtual ErrCode get_char(char * valueBuf)const;
virtual ErrCode get_uchar(unsigned char * valueBuf)const;
virtual ErrCode get_int16(int16_t * valueBuf)const;
virtual ErrCode get_uint16(u_int16_t * valueBuf)const;
virtual ErrCode get_int32(int * valueBuf)const;
virtual ErrCode get_uint32(u_int32_t * valueBuf)const;
virtual ErrCode get_int64(long long * valueBuf)const;
virtual ErrCode get_uint64(unsigned long long * valueBuf)const;
virtual ErrCode get_float(float * valueBuf)const;
virtual ErrCode get_double(double * valueBuf)const;
virtual ErrCode get_bsl_string(bsl_string * valueBuf)const;
//virtual ErrCode get_std_string(std_string * valueBuf) const;
virtual ErrCode get_raw_string(str_t * valueBuf) const;
//获取C风格的字符串,将字符串填入valueBuf,len是valueBuf长度,自动补0,最多填充len-1个字符
virtual ErrCode get_cstr(char * valueBuf, size_t len) const;
/**
* @brief 带有默认值的ge_XXX系列函数
* 返回值与get_xxx系列完全相同。
* 唯一的不同是:当返回值不为0(即发生错误)valueBuf中使用def默认值
*
* @param [out] valueBuf : char* 传出的值
* @param [in] def : const char& 默认值
* @return ErrCode
* @retval
* @see
* @author yingxiang
* @date 2009/03/11 22:37:46
**/
virtual ErrCode get_char(char * valueBuf, const char & def)const;
virtual ErrCode get_uchar(unsigned char * valueBuf, const unsigned char & def)const;
virtual ErrCode get_int16(int16_t * valueBuf, const int16_t & def)const;
virtual ErrCode get_uint16(u_int16_t * valueBuf, const u_int16_t & def)const;
virtual ErrCode get_int32(int * valueBuf, const int & def)const;
virtual ErrCode get_uint32(u_int32_t * valueBuf, const u_int32_t & def)const;
virtual ErrCode get_int64(long long * valueBuf, const long long & def)const;
virtual ErrCode get_uint64(unsigned long long * valueBuf, const unsigned long long & def)const;
virtual ErrCode get_float(float * valueBuf, const float & def)const;
virtual ErrCode get_double(double * valueBuf, const double & def)const;
virtual ErrCode get_bsl_string(bsl_string * valueBuf, const bsl_string & def)const;
virtual ErrCode get_raw_string(str_t * valueBuf, const str_t & def)const;
virtual ErrCode get_cstr(char * valueBuf, size_t len, const char * def)const;
/**
* @brief 将自身转化为一个IVar
*
* 会抛异常
*
* @param [in/out] vpool : VarPool* IVar句柄表,所以新分配的IVar都注册到VarPool
* 当需要销毁我创建的IVar时,只需要vpool->destroy();
* @param [in] errCode : ErrCode* 错误号,0为正确,其余表示出错
* @return IVar&
* @retval
* @see
* @author yingxiang
* @date 2009/03/11 22:00:48
**/
virtual bsl::var::IVar& to_IVar(bsl::ResourcePool* vpool, ErrCode* errCode = NULL)const;
/**
* @brief 获取自己的类型
*
* @return int
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:35:27
**/
virtual int selfType()const{
return CONFIG_UNIT_TYPE;
}
/**
* @brief 获取元素个数
*
* @return size_t 个数
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 02:00:28
**/
virtual size_t size()const{
return 1;
}
/**
* @brief 长路径Unit的直接获取
*
* @param [in] path : const str_t 长路径,例如 group.sub.key
* @return const ConfigUnit& 长路径获取的ConfigUnit
* @date 2009/07/16 15:50:47
**/
virtual const ConfigUnit & deepGet(const str_t path) const;
/**
* @brief 访问不存在的key后,给出不存在的key的具体路径。比如 group.sub.nokey
*
* @return const char* 不存在的key的路径
* @author zhang_rui
* @date 2009/07/17 10:20:09
**/
const char * getErrKeyPath() const;
/**
* @brief 获取子unit。ConfigUnit直接返回error unit
*
* @return ConfigUnit &
* @author zhang_rui
**/
virtual const ConfigUnit & get_sub_unit(int index) const;
/**
* @brief 比较是否相等
*
* @return int 0表示相等 -1不相等
* @author zhang_rui
**/
virtual int equals(const ConfigUnit & conf) const;
//以下函数的参数中,except为0则用错误号表示错误,
//except为1则用异常表示错误
/**
* @brief 增加一个unit, 连接到子unit,不做深拷贝
*
* @param [in] key : 新增unit的key
* @param [in] value : 新增unit的value
* @param [in] objtype : unit类型。
* CONFIG_UNIT_TYPE表示unit;
* CONFIG_GROUP_TYPE表示group;
* CONFIG_ARRAY_TYPE表示array;
* @return int 0 成功,其他是错误号
* @author zhang_rui
**/
virtual int add_unit(const bsl_string & key, const bsl_string& value,
const int objtype=CONFIG_UNIT_TYPE, int except=0, ConfigUnit ** ref=NULL);
/**
* @brief 复制一个unit, 深拷贝
*
* 将unit的内容追加到本对象下面。
* 类型需要匹配,只能从group复制到group,array复制到array
* group要检查key是否重复,不重复则追加
* array直接追加
* @return int 0 成功,其他是错误号
* @author zhang_rui
**/
virtual int append_unit(const ConfigUnit & unit, int except=0);
/**
* @brief 复制一个unit, 深拷贝
*
* 将unit的内容复制到本对象。
* 类型需要匹配,只能从group复制到group,array复制到array
* @return int 0 成功,其他是错误号
* @author zhang_rui
**/
virtual int copy_unit(const ConfigUnit & unit, int except=0);
/**
* @brief 删除一个unit
*
* key : 要删除的unit的key
* @return int 0 成功,其他是错误号
* @author zhang_rui
**/
virtual int del_unit(const bsl_string & key, int except=0);
/**
* @brief 修改unit中value的值
*
* @return int 0 成功,其他是错误号
* @author zhang_rui
**/
virtual int set_value(const bsl_string & value, int except=0);
/**
* @brief 遍历load()完成后的comcfg::Configure结构,使用用户提供的callback函数对每个unit进行操作
* @note 深度优先搜索,子节点的访问无先后顺序
* @param [in] cb_fn: 用户提供的callback函数
* @param [in] cb_arg: 用户callback函数所需要的参数
*
* @return int 0 成功,其他是错误号
* @author linjieqiong
**/
typedef int (* cb_tr)(ConfigUnit *, void *);
virtual int traverse_unit(cb_tr cb_fn, void *cb_arg);
/**
* @brief 类似于traverse_unit(),区别是遍历一个group时按照CONFIG_ERROR_TYPE, CONFIG_UNIT_TYPE, CONFIG_ARRAY_TYPE, CONFIG_GROUP_TYPE的顺序访问子节点
*
* @param [in] cb_fn: 用户提供的callback函数
* @param [in] cb_arg: 用户callback函数所需要的参数
*
* @return int 0 成功,其他是错误号
*
* @version 1.2.9
* @author linjieqiong
* @date 2013/04/28 16:25:47
*/
virtual int traverse_unit_order(cb_tr cb_fn, void *cb_arg);
//-----------------从这里往下的东西用户不需要关心-----------------
//构造函数,
ConfigUnit();
ConfigUnit(const str_t& __key, const str_t& __value, const Reader * __cur_reader = NULL, ConfigGroup * father = NULL);
//调试打印时用,缩进
void pindent(int ind)const{
while(ind--){
printf(" ");
}
}
//打印
virtual void print(int indent = 0)const{
pindent(indent);
printf("=[%s], _value=[%s]\n", _key.c_str(), _value.c_str());
}
//for debug or writelog
virtual str_t info() const{
//const int INFO_BUF_SIZE = 256;
//char buf[INFO_BUF_SIZE] = "";
str_t buf;
buf.appendf("[File:%s Line:%d Key:%s Value:%s]",
_at_file ? _at_file : "NULL", _at_line, _key.c_str(), _value.c_str());
return buf;
}
//for child class
virtual ConfigUnit * relativeSection(ConfigUnit *, str_t, int* ){
return NULL;
}
inline const char * getFileName(){
return _at_file;
}
inline int getFileLine(){
return _at_line;
}
inline void setConstrainted(const bool bCons){
_bConstrainted = bCons;
}
inline bool getConstrainted()const{
return _bConstrainted;
}
static ConfigUnit* get_err_unit();
virtual void get_full_path(bsl::string &path, const int get_global = 0) const;
inline virtual const bsl::string & get_key_name() const{
return _key;
}
inline ConfigGroup * getFather()const{
return _father;
}
protected:
inline void setFilePosition(const char *cur_file = "NULL", const int cur_line = -1){
_at_file = cur_file;
_at_line = cur_line;
}
inline void setFileLine(const int cur_line = -1){
_at_line = cur_line;
}
virtual void popError(ErrCode *, ErrCode) const;
void setErrorKeyPath(str_t str)const;
#if __GNUC__ == 4 && __GNUC_MINOR__ >= 4
const ConfigUnit & deepGetSegment(const str_t segment) const;
#else
const ConfigUnit & ConfigUnit :: deepGetSegment(const str_t segment) const;
#endif
static const str_t g_unknown;
str_t _key;
str_t _value;
str_t _cstr; //专门的一个被解析后的string,只有当value以"为开头时才起作用
int _cstr_err;
str_t _vstring;
const char * _at_file;
int _at_line;
ConfigGroup * _father;
bool _bConstrainted;
//mutable str_t _to_def_str;
ConfigUnit * create_unit(const bsl_string & key, const bsl_string& value,
int objtype, ConfigGroup * father);
/**
* @brief 清除内容
*
* @return void
* @author zhang_rui
**/
virtual void clear();
public:
/**
* @brief 复制一个unit, 深拷贝
*
* 将unit的内容复制到本对象下面。
* 类型需要匹配,只能从group复制到group,array复制到array
* group要检查key是否重复,不重复则追加
* array直接追加
* @return int 0 成功,其他是错误号
* @author zhang_rui
**/
virtual int _append_unit(const ConfigUnit & unit,int check=1, int except=0);
private:
int init_unit(const str_t& __key, const str_t& __value);
//访问类型为type的子节点,如果子节点是group/array,递归访问
int traverse_sub_type(cb_tr cb_fn, void *cv_arg, const int type);
};
}
#endif //__CONFIGUNIT_H_
/* vim: set ts=4 sw=4 sts=4 tw=100 */
此差异已折叠。
/***************************************************************************
*
* Copyright (c) 2008 Baidu.com, Inc. All Rights Reserved
* $Id: Configure.h,v 1.15 2010/04/13 09:59:41 scmpf Exp $
*
**************************************************************************/
/**
* @file Configure.h
* @author yingxiang(com@baidu.com)
* @date 2008/12/21 17:59:12
* @version $Revision: 1.15 $
* @brief 新的Configure库
* 更多资料请参见:
* http://com.baidu.com/twiki/bin/view/Main/LibConfig
*
**/
#ifndef __CONFIGURE_H_
#define __CONFIGURE_H_
#include "ConfigGroup.h"
#include "sys/uio.h"
#include <vector>
#define CONFIG_GLOBAL "GLOBAL"
#define CONFIG_INCLUDE "$include"
namespace confIDL{
struct idl_t;
}
namespace comcfg{
const int MAX_INCLUDE_DEPTH = 1;
class Reader;
enum{
CONFIG_VERSION_1_0, //Config Version 1.0
};
/**
* @brief 配置句柄,其实是一个全局的[GLOBAL]配置组
*
* Configure是immutable的,即:无法修改,无法复用
* 所以load, rebuild, loadIVar三个接口互斥
* 要重新load,必须创建一个新的Configure句柄进行操作
*
*/
class Configure : public ConfigGroup{
public:
/**
* @brief 从指定的文件中载入配置文件和约束文件
*
* @param [in] path : const char* 配置文件的路径
* @param [in] conf : const char* 配置文件名
* @param [in] range : const char* 约束文件
* @param [in] version : int 文件格式的版本(暂未使用)
* @return int 0表示成功,其余为失败
* bsl::CONSTRAINT_ERROR 约束检查错误(如果不关心约束,可无视此错误)
* bsl::CONFIG_ERROR 配置文件解析错误
* bsl::ERROR 其它错误
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:36:54
**/
int load(const char * path, const char * conf, const char * range = NULL, int version = CONFIG_VERSION_1_0);
/**
* @brief 从指定的文件中载入配置文件和约束文件,并检查是否有group重名情况,最后打印到日志
* 默认行为与load()接口相同
*
* @param [in] path : const char* 配置文件的路径
* @param [in] conf : const char* 配置文件名
* @param [in] range : const char* 约束文件
* @param [in] dupLevel : enum GROUP_DUP_LEVEL 指定的重名等级,下列值之一
* 0: GROUP_DUP_LEVEL0 不检测是否有重名,与原接口行为相同,不打印
* 1: GROUP_DUP_LEVEL1 检测第一级group是否重名
* 2: GROUP_DUP_LEVEL2 检测所有深度下group是否重名
* 3: GROUP_DUP_LEVEL3 记录所有group名
* @param [in] version : int 文件格式的版本(暂未使用)
* @return int 0表示成功,其他值为失败
* bsl::CONSTRAINT_ERROR 约束检查错误(如果不关心约束,可无视此错误)
* bsl::CONFIG_ERROR 配置文件解析错误
* bsl::ERROR 其它错误
* DUPLICATED_GROUP 有组重名,在GROUP_DUP_LEVEL0和GROUP_DUP_LEVEL3下,正常则返回0
* @retval
* @see
* @author linjieqiong
* @date 20012/12/28 11:36:54
**/
int load_ex(const char * path, const char * conf, const char * range = NULL,
int dupLevel = GROUP_DUP_LEVEL0, int version = CONFIG_VERSION_1_0);
/**
* @brief 从指定的文件中载入配置文件和约束文件,如果存在未被约束的配置项,则打印并报错
*
* @param [in] path : const char* 配置文件的路径
* @param [in] conf : const char* 配置文件名
* @param [in] range : const char* 约束文件,如果指定了约束文件,则会在会后打印出未被约束的配置项
* @param [in] version : int 文件格式的版本(暂未使用)
* @return int 0表示成功,其余为失败
* bsl::CONSTRAINT_ERROR 约束检查错误(不满足约束,存在未被约束的配置项)(如果不关心约束,可无视此错误)
* bsl::CONFIG_ERROR 配置文件解析错误
* bsl::ERROR 其它错误
* @retval
* @see
* @author linjieqiong
* @date 2013/01/06 21:36:54
**/
int load_ex2(const char * path, const char * conf, const char * range = NULL, int version = CONFIG_VERSION_1_0);
/**
* @brief 将数据串行化到一个字节流,可以发网网络
* 如果将这个字节流直接写入磁盘文件,不可以直接load回来,而需要读取后再rebuild
* @note 本api只能序列化原始配置文件镜像或ivar,不能反映在内存中对configure对象的修改
* 如需序列化实时内容,请使用dump_ex()
*
* @param [out] size_t * : 输出的字节流长度
* @return char* 输出的字节流
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:38:35
**/
char * dump(size_t *);
/**
* @brief 序列化configure对象的实时内存内容
*
* @param [in] buf : dump_ex()输出的位置
* @param [in] bufsize : buf的长度
* @param [in] restoreComment : const int
* 0 RC_COMMENT 还原配置文件中的注释到输出
* 1 RC_NO_COMMENT 不还原配置文件中的注释内容到输出
* 2 RC_POSITION 还原的同时标记配置项在配置文件中的位置,格式:
* #this is the original comment
* #[FILE:LINE]
* [group]
* #[FILE:LINE]
* key : value
*
* @return int 写入buf的数据长度
* 如果发生错误,返回-1
* 如果buf不够,返回实际长度的相反数
* 自动添加\0
*
* @author linjieqiong
* @version 1.2.9
* @date 2013/04/24 14:56:31
*/
int dump_ex(char *buf, const size_t bufsize, const int restoreComment = 0);
/**
* @brief 根据dump的字节流创建Configure
* 根据字节流重建一个Configure的步骤是:
* 1,getRebuildBuffer(size) 获取一个内部缓冲区
* 2,将字节流中的数据拷贝到这个缓冲区
* 3,调用rebuild重建数据
*
* 调用本接口会清空现有的数据。
*
* @param [in] size : size_t 字节流长度
* @return char* 缓冲区
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:39:38
**/
char * getRebuildBuffer(size_t size);
/**
* @brief 根据获得的字节流重建Configure数据
*
* @return int 0为成功,其他为失败
* @retval
* @see
* @author yingxiang
* @date 2008/12/30 01:43:05
**/
int rebuild();
/**
* @brief 检查所有配置文件的最后更新时间(包括被$include)的配置文件
* $include 限制层数为:MAX_INCLUDE_DEPTH
* 在执行lastConfigModify(),应确保原来的配置文件都没有被删除
*
* @return time_t 所有配置文件中的最后更新时间
* 返回0表示出错
* @retval
* @see
* @author yingxiang
* @date 2009/03/10 14:23:47
**/
time_t lastConfigModify();
/**
* @brief 从一个IVar载入配置文件的数据
* 本接口与load/rebuild互斥
* 这个IVar必须是一个Dict类型
*
* @return int 0成功,其余失败
* @retval
* @see
* @author yingxiang
* @date 2009/03/11 17:29:56
**/
int loadIVar(const bsl::var::IVar & );
/**
* @brief 用约束文件检查一次
* @param [in] range : const char* 约束文件
* @param [in] version : int 文件格式的版本(暂未使用)
* @return int 0表示成功,其余为失败
* bsl::CONSTRAINT_ERROR 约束检查错误
* bsl::ERROR 其它错误
**/
int check_once(const char * range, int version = CONFIG_VERSION_1_0);
/**
* @brief 检查conf文件中所有unit是否被约束,如果存在未被约束的项,则打印并返回错误
*
* @return int 0 成功,其他是错误号
* bsl::CONSTRAINT_ERROR 约束检查错误
* @author linjieqiong
* @date 2013/01/07 17:32:10
**/
int checkConstraint();
/**
* @brief 获取一个key的约束函数列表,注意group和array类型的约束函数是无作用的
* @param [in] key_path : const char* 该key在conf文件中的完整路径
* @param [in] range : const char* 约束文件,
* 如果非空,先进行约束检查;
* 如果为空,将使用最近一次load类函数或check_once()函数所使用的约束文件
*
* @return int 0 成功,其他是错误号
* bsl::CONSTRAINT_ERROR 约束检查错误
* bsl::ERROR 其它错误
*
* @author linjieqiong
* @date 2013/01/10 10:50:00
**/
int printKeyConstraint(const char *key_path, const char *range = NULL);
virtual ConfigUnit & operator= (ConfigUnit & unit) {
return ConfigUnit::operator=(unit);
}
Configure();
~Configure();
protected:
int load_1_0(const char * path, const char * conf, const char *range);
void pushSubReader(const char * conf, int level = -1);
friend class Reader;
friend class Constraint;
friend class ConfigGroup;
friend class ConfigUnit;
friend struct dump_conf;
friend int cb_dumpConf(ConfigUnit *, void *);
struct ReaderNode{//每一个conf文件
str_t filename;
Reader * reader;
int level;
};
std::vector <ReaderNode *> _readers;
str_t _path;
Reader * _cur_reader;//当前在处理的文件
int _cur_level;//当前文件的深度($include的层次)
char * _dump_buffer;
size_t _dump_size;
confIDL::idl_t * _idl;
void changeSection(str_t str);
void pushPair(const str_t& key, const str_t& value);
ConfigGroup* _section;
//depth是一个调试变量
int _depth;
};
}
#endif //__CONFIGURE_H_
/* vim: set ts=4 sw=4 sts=4 tw=100 */
/***************************************************************************
*
* Copyright (c) 2009 Baidu.com, Inc. All Rights Reserved
* EnvGet.h 2009/07/17 14:24:22 zhang_rui Exp
*
**************************************************************************/
/**
* @file EnvGet.h
* @author zhang_rui(com@baidu.com)
* @date 2009/07/17 14:24:22
* @brief
*
**/
#ifndef __ENVGET_H_
#define __ENVGET_H_
#include "utils/cc_struct.h"
#define ENV_CHAR_DECL(envstr, deft) \
static const char g_char_##envstr = (NULL == getenv(#envstr))? \
deft : getenv(#envstr)[0]
#define ENV_UCHAR_DECL(envstr, deft) \
static const unsigned char g_uchar_##envstr = (NULL == getenv(#envstr))? \
deft : (unsigned char)getenv(#envstr)[0]
#define ENV_INT16_DECL(envstr, deft) \
static const int16_t g_int16_##envstr = (NULL == getenv(#envstr))? \
deft : (int16_t)strtoll(getenv(#envstr), NULL, 0)
#define ENV_UINT16_DECL(envstr, deft) \
static const u_int16_t g_uint16_##envstr = (NULL == getenv(#envstr))? \
deft : (u_int16_t)strtoll(getenv(#envstr), NULL, 0)
#define ENV_INT32_DECL(envstr, deft) \
static const int g_int32_##envstr = (NULL == getenv(#envstr))? \
deft : (int)strtoll(getenv(#envstr), NULL, 0)
#define ENV_UINT32_DECL(envstr, deft) \
static const u_int32_t g_uint32_##envstr = (NULL == getenv(#envstr))? \
deft : (u_int32_t)strtoll(getenv(#envstr), NULL, 0)
#define ENV_INT64_DECL(envstr, deft) \
static const long long g_int64_##envstr = (NULL == getenv(#envstr))? \
deft : (long long)strtoll(getenv(#envstr), NULL, 0)
#define ENV_UINT64_DECL(envstr, deft) \
static const unsigned long long g_uint64_##envstr = (NULL == getenv(#envstr))? \
deft : (unsigned long long)strtoull(getenv(#envstr), NULL, 0)
#define ENV_FLOAT_DECL(envstr, deft) \
static const float g_float_##envstr = (NULL == getenv(#envstr))? \
deft : (float)strtod(getenv(#envstr), NULL)
#define ENV_DOUBLE_DECL(envstr, deft) \
static const float g_double_##envstr = (NULL == getenv(#envstr))? \
deft : (double)strtod(getenv(#envstr), NULL)
#define ENV_BSLSTR_DECL(envstr, deft) \
static const bsl_string g_bslstr_##envstr = (NULL == getenv(#envstr))? \
deft : bsl_string(getenv(#envstr))
#endif //__ENVGET_H_
/* vim: set ts=4 sw=4 sts=4 tw=100 */
/***************************************************************************
*
* Copyright (c) 2010 Baidu.com, Inc. All Rights Reserved
*
**************************************************************************/
/**
* @file FileReloader.cpp
* @author zhang_rui(com@baidu.com)
* @date 2010-2-1
* @brief
*
**/
#include "FileReloader.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
namespace comcfg {
static time_t get_file_time(const char * filename) {
if (NULL == filename) {
LOG(WARNING) << "FileReloader.add_file_monitor : NULL filename";
return -1;
}
time_t t = time_t(0);
struct stat st;
if(stat(filename, &st) == 0){
if(t < st.st_mtime){
t = st.st_mtime;
}
} else {
LOG(WARNING) << "FileReloader add_file_monitor : Can not stat file " << filename;
return -1;
}
return t;
}
int FileReloader :: monitor() {
int ret = 0;
bsl::hashmap <bsl::string, config_filemonitor_t *> :: iterator itr;
for(itr = _filemap.begin(); itr != _filemap.end(); ++itr){
config_filemonitor_t * fm = itr->second;
time_t tnow = get_file_time(itr->first.c_str());
if (tnow<0) {
return -1;
}
if (tnow > fm->_last_modify) {
fm->_last_modify = tnow;
fm->callback(itr->first.c_str(), fm->param);
++ret;
}
}
return ret;
}
int FileReloader :: add_file_monitor(const char * filename, file_change_cb_t proc, void * prm) {
if (NULL == filename) {
LOG(WARNING) << "FileReloader.add_file_monitor : NULL filename";
return -1;
}
if (NULL == proc) {
LOG(WARNING) << "FileReloader.add_file_monitor : NULL callback";
return -1;
}
if (!_filemap.is_created())
{
LOG(WARNING) << "Initial FileReloader : create filemap";
_filemap.create(256);
}
time_t t = get_file_time(filename);
if (0 > t) {
return -1;
}
config_filemonitor_t * pmon = new config_filemonitor_t;
pmon->callback = proc;
pmon->param = prm;
pmon->_last_modify = t;
bsl::string kstr = filename;
bsl::hashmap <bsl::string, config_filemonitor_t *> :: _Pair *itr;
itr = _filemap.find(kstr);
if(NULL != itr) {
if (NULL != itr->second){
delete itr->second;
}
LOG(WARNING) << "FileReloader.add_file_monitor : same file("<< filename << ") exist, update callback(" << proc << "), param(" << prm << ")";
}
_filemap.set(kstr,pmon,1);
return 0;
}
FileReloader :: ~FileReloader() {
bsl::hashmap<bsl::string, config_filemonitor_t *>::iterator itr;
for(itr = _filemap.begin(); itr != _filemap.end(); ++itr) {
if (NULL != itr->second) {
delete itr->second;
}
}
if(0 != _filemap.destroy()){
LOG(WARNING) << "FileReloader.~FileReloader : _filemap.destory() failed ";
}
}
}//namespace comcfg
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册