mirror of
https://gitee.com/jiuyilian/embedded-framework.git
synced 2025-01-06 10:16:51 -05:00
Pre Merge pull request !1 from chenhaijian/master
This commit is contained in:
commit
32ca3f3301
84
Environmental.md
Normal file
84
Environmental.md
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
# 前期需要下载的软件
|
||||||
|
* VMware Workstration
|
||||||
|
* git bash
|
||||||
|
* vscode
|
||||||
|
* Beyond Compare
|
||||||
|
* MoBaXterm
|
||||||
|
|
||||||
|
# 前期快速上手
|
||||||
|
* git的基本操作(我们主要使用git进行代码管理)
|
||||||
|
* Linux的基本操作(主要是命令行操作,了解常用的命令,了解怎么使用命令行管理文件)
|
||||||
|
//csdn相关文章写得很详尽,搭配上ai工具边用边学可以很快地熟悉常用的指令
|
||||||
|
|
||||||
|
|
||||||
|
# 前期需要准备的基本环境
|
||||||
|
1. 在VMware Workstation中安装Ubuntu,安装好gcc和g++编译器,并配置好网络(能正常上网)
|
||||||
|
2. 学会vscode用ssh远程连接Ubuntu,下载CMake、CMake Tools、Baidu Comate(ai工具,对后续学习有比较大的帮助)等基本插件
|
||||||
|
3. 创建一个gitee账号
|
||||||
|
|
||||||
|
# 编译过程
|
||||||
|
1. 将gitee上的源码文件保存到虚拟机中
|
||||||
|
2. 依照顺序执行以下命令
|
||||||
|
|
||||||
|
|
||||||
|
* 安装libssl-dev软件包
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install openssl
|
||||||
|
sudo apt-get install libssl-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
* 安装LDAP软件包
|
||||||
|
```
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install libldap2-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
* 安装cmake(llvm使用cmake编译,cmake版本要求 3.20以上,此处安装cmake-3.27.4)
|
||||||
|
cmake源码压缩包所在的路径:embedded-framework/tools/cmake/cmake-3.27.4.tar.gz
|
||||||
|
在embedded-framework/tools/cmake目录下执行以下指令来安装cmake-3.27.4:
|
||||||
|
```
|
||||||
|
tar zxvf cmake-3.27.4.tar.gz
|
||||||
|
cd cmake-3.27.4
|
||||||
|
sudo apt-get install openssl // 如果执行./bootstrap提示缺少ssl相关资源,执行此安装命令
|
||||||
|
./bootstrap
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
|
cmake --version //查看版本,确认安装完成
|
||||||
|
```
|
||||||
|
|
||||||
|
* 安装llvm
|
||||||
|
```
|
||||||
|
// 下载源码
|
||||||
|
git clone https://github.com/llvm/llvm-project.git
|
||||||
|
cd llvm-project
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="X86" -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" ../llvm
|
||||||
|
make -j8 //这个过程会有点久
|
||||||
|
find ./ -name clang-tidy //查看是否有clang-tidy的文件
|
||||||
|
clang-tidy --version //查看版本,确认编译完成
|
||||||
|
```
|
||||||
|
|
||||||
|
3. 进行编译,在embedded-framework目录下执行以下命令:
|
||||||
|
```
|
||||||
|
make clean //CmakeLists.txt是生成Makefile文件的构建脚本,如果CmakeLists.txt被修改需要重新执行make clean清除之前的构建文件
|
||||||
|
make cmake //构建源码,生成Makefile文件
|
||||||
|
cd cmake-shell //在中间文件目录进行编译,把所有中间文件创建在此
|
||||||
|
make //编译全部输出构建文件
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 问题汇总
|
||||||
|
1. gcc编译器版本过低后续编译会出bug,亲测gcc 7.5.0版本不能用,可以使用gcc --version命令查看自己gcc的版本,版本过低需要更新版本,可以自行搜索怎么更新也可以参考https://blog.csdn.net/weixin_43354152/article/details/129247408
|
||||||
|
|
||||||
|
2. 下载llvm源码时git clone https://github.com/llvm/llvm-project.git 这个过程可能会经常报网络错误,多试几次,可以用网易uu加速器的学术资源加速可能会好下一点
|
||||||
|
|
||||||
|
3. 编译llvm过程可能会多次卡顿退出,可能的原因有:磁盘空间不足、编译器版本过低、缺少依赖等。可以尝试多线程编译(make -j8)
|
3
bug.md
Normal file
3
bug.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# 仓库中隐藏的bug
|
||||||
|
1. “小”指针强制转换成“大”指针,可能造成内存的非法操作
|
||||||
|
* embedded.framework/utils/confaBase /src/ConfigBaselmpl.cpp
|
|
@ -16,6 +16,7 @@
|
||||||
#define I_FILES_MANAGER_H
|
#define I_FILES_MANAGER_H
|
||||||
#include "StatusCode.h"
|
#include "StatusCode.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
typedef struct save_file_info
|
typedef struct save_file_info
|
||||||
{
|
{
|
||||||
save_file_info(const std::string &fileName);
|
save_file_info(const std::string &fileName);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "StatusCode.h"
|
#include "StatusCode.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
bool CreateMediaManagerModule(void);
|
bool CreateMediaManagerModule(void);
|
||||||
bool DestroyMediaManagerModule(void);
|
bool DestroyMediaManagerModule(void);
|
||||||
enum class MediaChannel
|
enum class MediaChannel
|
||||||
|
|
|
@ -9,8 +9,10 @@ include_directories(
|
||||||
${UTILS_SOURCE_PATH}/Log/include
|
${UTILS_SOURCE_PATH}/Log/include
|
||||||
${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include
|
${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include
|
||||||
${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/include
|
${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/include
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
link_directories(
|
link_directories(
|
||||||
${LIBS_OUTPUT_PATH}
|
${LIBS_OUTPUT_PATH}
|
||||||
${EXTERNAL_LIBS_OUTPUT_PATH}
|
${EXTERNAL_LIBS_OUTPUT_PATH}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
#include "ILog.h"
|
#include "ILog.h"
|
||||||
// #include <gmock/gmock.h>
|
// #include <gmock/gmock.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
@ -6,6 +7,7 @@ namespace ILogTest
|
||||||
// ../output_files/test/bin/LogTest --gtest_filter=ILogTest.Demo
|
// ../output_files/test/bin/LogTest --gtest_filter=ILogTest.Demo
|
||||||
TEST(ILogTest, Demo)
|
TEST(ILogTest, Demo)
|
||||||
{
|
{
|
||||||
|
|
||||||
CreateLogModule();
|
CreateLogModule();
|
||||||
ILogInit(LOG_INSTANCE_TYPE_END);
|
ILogInit(LOG_INSTANCE_TYPE_END);
|
||||||
LogInfo("hello world.");
|
LogInfo("hello world.");
|
||||||
|
|
|
@ -1,52 +1,56 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 Fancy Code.
|
* Copyright (c) 2023 Fancy Code.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef CONFIG_BASE_H
|
#ifndef CONFIG_BASE_H
|
||||||
#define CONFIG_BASE_H
|
#define CONFIG_BASE_H
|
||||||
#include "StatusCode.h"
|
#include "StatusCode.h"
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" //The declaration is to allow the C++compiler to process code surrounded by extern "C" in the same way as the C language. This is necessary
|
||||||
#endif
|
{
|
||||||
enum CONFIG_CODE
|
#endif
|
||||||
{
|
//#The three preprocessing instructions ifndef VNet BASE.H, # define VNet BASE.H, and # endif work together to ensure that the header file VNet BASE.H is only included once in any compilation unit. This is achieved by defining a unique macro (VNet BASE_H), skipping the file content if the macro has already been defined.
|
||||||
CONFIG_CODE_PARAM_NOT_EXIST = STATUS_CODE_END,
|
enum CONFIG_CODE//Defined an enumeration type VNet CODE for possible configuration error codes. It starts with VNet CODE-IND (assuming VNet CODE-IND is a status code defined in Status Code. h, indicating the end of a set of status codes), and defines a VNet CODE-IND as the end flag for enumeration.
|
||||||
CONFIG_CODE_END
|
{
|
||||||
};
|
CONFIG_CODE_PARAM_NOT_EXIST = STATUS_CODE_END,
|
||||||
// StatusCode ConfigInit(void);
|
CONFIG_CODE_END
|
||||||
// StatusCode ConfigUnInit(void);
|
};
|
||||||
void *OpenConfigFile(const char *fileName);
|
// StatusCode ConfigInit(void);
|
||||||
StatusCode ConfigSaveFile(void *object);
|
// StatusCode ConfigUnInit(void);
|
||||||
void CloseConfigFile(void *object);
|
void *OpenConfigFile(const char *fileName);
|
||||||
StatusCode ConfigGetInt(void *object, const char *name, int *value);
|
StatusCode ConfigSaveFile(void *object);
|
||||||
StatusCode ConfigSetInt(void *object, const char *name, const int value);
|
void CloseConfigFile(void *object);
|
||||||
StatusCode ConfigGetShort(void *object, const char *name, short *value);
|
StatusCode ConfigGetInt(void *object, const char *name, int *value);
|
||||||
StatusCode ConfigSetShort(void *object, const char *name, const short value);
|
StatusCode ConfigSetInt(void *object, const char *name, const int value);
|
||||||
StatusCode ConfigGetLong(void *object, const char *name, long *value);
|
StatusCode ConfigGetShort(void *object, const char *name, short *value);
|
||||||
StatusCode ConfigSetLong(void *object, const char *name, const long value);
|
StatusCode ConfigSetShort(void *object, const char *name, const short value);
|
||||||
StatusCode ConfigGetLLong(void *object, const char *name, long long *value);
|
StatusCode ConfigGetLong(void *object, const char *name, long *value);
|
||||||
StatusCode ConfigSetLLong(void *object, const char *name, const long long value);
|
StatusCode ConfigSetLong(void *object, const char *name, const long value);
|
||||||
StatusCode ConfigGetChar(void *object, const char *name, char *value);
|
StatusCode ConfigGetLLong(void *object, const char *name, long long *value);
|
||||||
StatusCode ConfigSetChar(void *object, const char *name, const char value);
|
StatusCode ConfigSetLLong(void *object, const char *name, const long long value);
|
||||||
StatusCode ConfigGetBool(void *object, const char *name, bool *value);
|
StatusCode ConfigGetChar(void *object, const char *name, char *value);
|
||||||
StatusCode ConfigSetBool(void *object, const char *name, const bool value);
|
StatusCode ConfigSetChar(void *object, const char *name, const char value);
|
||||||
StatusCode ConfigGetFloat(void *object, const char *name, float *value);
|
StatusCode ConfigGetBool(void *object, const char *name, bool *value);
|
||||||
StatusCode ConfigSetFloat(void *object, const char *name, const float value);
|
StatusCode ConfigSetBool(void *object, const char *name, const bool value);
|
||||||
StatusCode ConfigGetDouble(void *object, const char *name, double *value);
|
StatusCode ConfigGetFloat(void *object, const char *name, float *value);
|
||||||
StatusCode ConfigSetDouble(void *object, const char *name, const double value);
|
StatusCode ConfigSetFloat(void *object, const char *name, const float value);
|
||||||
StatusCode ConfigGetString(void *object, const char *name, const char **value);
|
StatusCode ConfigGetDouble(void *object, const char *name, double *value);
|
||||||
StatusCode ConfigSetString(void *object, const char *name, const char *value);
|
StatusCode ConfigSetDouble(void *object, const char *name, const double value);
|
||||||
#ifdef __cplusplus
|
StatusCode ConfigGetString(void *object, const char *name, const char **value);
|
||||||
}
|
StatusCode ConfigSetString(void *object, const char *name, const char *value);
|
||||||
#endif
|
//Provides a series of functions for opening, saving, closing configuration files, as well as obtaining and setting values for different data types (such as integer, short integer, long integer, long integer, character, boolean, floating-point, double precision floating-point, and string) in the configuration file. Most of these functions accept a void * object as the first parameter, which is typically a pointer to the configuration file context or object used to access and manipulate the configuration file. Other parameters include the name of the configuration item (const char * name) and a pointer to the variable used to store the retrieved value (such as int * value).
|
||||||
#endif
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
//Overall, this header file defines a configuration management interface that allows developers to read and write configuration file values in a type safe manner, while considering interoperability between C and C++.
|
34
utils/ConfigBase/readme.md
Normal file
34
utils/ConfigBase/readme.md
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# CONFIGBASE
|
||||||
|
|
||||||
|
#涉及的知识
|
||||||
|
----------------------------------------------------------------
|
||||||
|
1.CMake
|
||||||
|
|
||||||
|
2.C/C++
|
||||||
|
|
||||||
|
3.配置文件
|
||||||
|
|
||||||
|
4.状态码
|
||||||
|
|
||||||
|
5.libconfig库
|
||||||
|
|
||||||
|
### 各文件的作用
|
||||||
|
*1.conffig_base.cmake:定义了一个名为config_owner的函数,该函数旨在为一个特定的CMake目标(比如一个可执行文件或库)的所有源文件添加一个新的编译定义(COMPILE_DEFINITIONS)。在这个上下文中,编译定义通常用于在编译时向源代码中注入宏定义,这些宏定义可以在源代码中被用作条件编译的开关。*
|
||||||
|
|
||||||
|
*2.ConfigBase.h:是一个C/C++兼容的头文件(CONFIG_BASE_H),它定义了一个配置管理的基础接口。这个接口提供了打开、保存、关闭配置文件以及获取和设置配置文件中不同类型数据的功能。*
|
||||||
|
|
||||||
|
*3.ConfigBase.cpp:实现了一个配置文件管理器的接口封装,它提供了一系列用于打开、关闭、保存配置文件以及获取和设置配置文件中的不同类型配置项的功能。*
|
||||||
|
|
||||||
|
*4.ConfigBaseCode.c:涉及到一个用于处理配置代码(ConfigCode)的系统,这些配置代码似乎是从一个更大的状态码(StatusCode)系统中派生出来的。代码依赖于几个自定义的类型和函数,包括StatusCode结构体、ILog接口(通过LogInfo和LogError宏或函数实现)、以及ConfigBase和ConfigBaseCode。*
|
||||||
|
|
||||||
|
*5.ConfigBaseCode.h:用于定义与配置代码相关的接口。它采用了C和C++的混合编程方式,并通过预处理器指令来控制代码的包含和编译。*
|
||||||
|
|
||||||
|
*6.ConfigBaselmpl.cpp:定义了一个名为ConfigBaseImpl的类,它用于处理基于文本的配置文件(如INI或类似格式的文件),使用libconfig库来实现这一功能。libconfig是一个用于处理结构化配置文件的C库,它支持读取和写入配置文件。ConfigBaseImpl类封装了libconfig的基本操作,如打开、关闭配置文件,以及读取和写入配置项的值。*
|
||||||
|
|
||||||
|
*7.ConfigBaselmpl.h:定义了一个名为 ConfigBaseImpl 的类,它实现了 IConfigBase 接口,用于处理配置文件。它使用了 libconfig 库来解析和生成配置文件。*
|
||||||
|
|
||||||
|
*8.lConfigBase.cpp:定义了一个名为 IConfigBase 的接口类,用于配置文件的操作,包括打开、关闭、读取和设置不同类型的配置值(如整数、短整数、长整数、长长整数、字符、布尔值、浮点数、双精度浮点数和字符串)。然而,这些函数的具体实现在 IConfigBase 类中都被设置为返回特定的状态码 STATUS_CODE_VIRTUAL_FUNCTION,这通常表示该函数是虚函数,需要在派生类中具体实现。*
|
||||||
|
|
||||||
|
*9.lConfigBase.h:定义了一个C++接口(IConfigBase)和一些相关的类型及函数声明,主要用于配置文件的操作。*
|
||||||
|
|
||||||
|
*10.CMakeLists.txt:是一个CMake脚本,用于配置和编译一个静态库项目(名为ConfigBase),并包含了一些额外的自定义目标和依赖管理。*
|
|
@ -1,183 +1,183 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 Fancy Code.
|
* Copyright (c) 2023 Fancy Code.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "ConfigBase.h"
|
#include "ConfigBase.h"
|
||||||
#include "IConfigBase.h"
|
#include "IConfigBase.h"
|
||||||
#include "ILog.h"
|
#include "ILog.h"
|
||||||
#include "StatusCode.h"
|
#include "StatusCode.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
static bool ObjectCheck(void *object)
|
static bool ObjectCheck(void *object)
|
||||||
{
|
{
|
||||||
if (nullptr == object) {
|
if (nullptr == object) {
|
||||||
LogError("nullptr object!\n");
|
LogError("nullptr object!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (*((const char **)(((char *)object) - sizeof(IConfigBaseHeader))) != GetConfigBaseModuleName()) {
|
if (*((const char **)(((char *)object) - sizeof(IConfigBaseHeader))) != GetConfigBaseModuleName()) {
|
||||||
LogError("Illegal object!\n");
|
LogError("Illegal object!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void *OpenConfigFile(const char *fileName)
|
void *OpenConfigFile(const char *fileName)
|
||||||
{
|
{
|
||||||
std::shared_ptr<IConfigBase> *configObject = NewConfigBase(fileName);
|
std::shared_ptr<IConfigBase> *configObject = NewConfigBase(fileName);
|
||||||
if (nullptr != configObject) {
|
if (nullptr != configObject) {
|
||||||
if ((*configObject)->OpenConfigFile() == false) {
|
if ((*configObject)->OpenConfigFile() == false) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return configObject;
|
return configObject;
|
||||||
}
|
}
|
||||||
StatusCode ConfigSaveFile(void *object)
|
StatusCode ConfigSaveFile(void *object)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSaveFile();
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSaveFile();
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
void CloseConfigFile(void *object)
|
void CloseConfigFile(void *object)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
(*(std::shared_ptr<IConfigBase> *)object)->CloseConfigFile();
|
(*(std::shared_ptr<IConfigBase> *)object)->CloseConfigFile();
|
||||||
(*(std::shared_ptr<IConfigBase> *)object).reset();
|
(*(std::shared_ptr<IConfigBase> *)object).reset();
|
||||||
free(((char *)object) - sizeof(IConfigBaseHeader)); // TODO: bug?
|
free(((char *)object) - sizeof(IConfigBaseHeader)); // TODO: bug?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatusCode ConfigGetInt(void *object, const char *name, int *value)
|
StatusCode ConfigGetInt(void *object, const char *name, int *value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetInt(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetInt(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigSetInt(void *object, const char *name, const int value)
|
StatusCode ConfigSetInt(void *object, const char *name, const int value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetInt(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetInt(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigGetShort(void *object, const char *name, short *value)
|
StatusCode ConfigGetShort(void *object, const char *name, short *value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetShort(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetShort(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigSetShort(void *object, const char *name, const short value)
|
StatusCode ConfigSetShort(void *object, const char *name, const short value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetShort(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetShort(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigGetLong(void *object, const char *name, long *value)
|
StatusCode ConfigGetLong(void *object, const char *name, long *value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetLong(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetLong(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigSetLong(void *object, const char *name, const long value)
|
StatusCode ConfigSetLong(void *object, const char *name, const long value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetLong(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetLong(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigGetLLong(void *object, const char *name, long long *value)
|
StatusCode ConfigGetLLong(void *object, const char *name, long long *value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetLLong(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetLLong(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigSetLLong(void *object, const char *name, const long long value)
|
StatusCode ConfigSetLLong(void *object, const char *name, const long long value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetLLong(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetLLong(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigGetChar(void *object, const char *name, char *value)
|
StatusCode ConfigGetChar(void *object, const char *name, char *value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetChar(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetChar(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigSetChar(void *object, const char *name, const char value)
|
StatusCode ConfigSetChar(void *object, const char *name, const char value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetChar(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetChar(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigGetBool(void *object, const char *name, bool *value)
|
StatusCode ConfigGetBool(void *object, const char *name, bool *value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetBool(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetBool(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigSetBool(void *object, const char *name, const bool value)
|
StatusCode ConfigSetBool(void *object, const char *name, const bool value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetBool(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetBool(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigGetFloat(void *object, const char *name, float *value)
|
StatusCode ConfigGetFloat(void *object, const char *name, float *value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetFloat(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetFloat(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigSetFloat(void *object, const char *name, const float value)
|
StatusCode ConfigSetFloat(void *object, const char *name, const float value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetFloat(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetFloat(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigGetDouble(void *object, const char *name, double *value)
|
StatusCode ConfigGetDouble(void *object, const char *name, double *value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetDouble(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetDouble(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigSetDouble(void *object, const char *name, const double value)
|
StatusCode ConfigSetDouble(void *object, const char *name, const double value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetDouble(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetDouble(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigGetString(void *object, const char *name, const char **value)
|
StatusCode ConfigGetString(void *object, const char *name, const char **value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetString(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigGetString(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
||||||
StatusCode ConfigSetString(void *object, const char *name, const char *value)
|
StatusCode ConfigSetString(void *object, const char *name, const char *value)
|
||||||
{
|
{
|
||||||
if (ObjectCheck(object) == true) {
|
if (ObjectCheck(object) == true) {
|
||||||
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetString(name, value);
|
return (*(std::shared_ptr<IConfigBase> *)object)->ConfigSetString(name, value);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
|
||||||
}
|
}
|
|
@ -1,55 +1,55 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 Fancy Code.
|
* Copyright (c) 2023 Fancy Code.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "ConfigBaseCode.h"
|
#include "ConfigBaseCode.h"
|
||||||
#include "ConfigBase.h"
|
#include "ConfigBase.h"
|
||||||
#include "ILog.h"
|
#include "ILog.h"
|
||||||
#include "StatusCode.h"
|
#include "StatusCode.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
static const char *ConfigCodeString[CONFIG_CODE_END - STATUS_CODE_END + 1] = {"CONFIG_CODE_PARAM_NOT_EXIST",
|
static const char *ConfigCodeString[CONFIG_CODE_END - STATUS_CODE_END + 1] = {"CONFIG_CODE_PARAM_NOT_EXIST",
|
||||||
"CONFIG_CODE_END"};
|
"CONFIG_CODE_END"};
|
||||||
static const char *PrintStringConfigCode(const StatusCode this)
|
static const char *PrintStringConfigCode(const StatusCode this)
|
||||||
{
|
{
|
||||||
const int CODE_INDEX = this.mStatusCode - STATUS_CODE_END;
|
const int CODE_INDEX = this.mStatusCode - STATUS_CODE_END;
|
||||||
if (STATUS_CODE_END <= this.mStatusCode && this.mStatusCode <= CONFIG_CODE_END) {
|
if (STATUS_CODE_END <= this.mStatusCode && this.mStatusCode <= CONFIG_CODE_END) {
|
||||||
LogInfo("Config code = [ %s ]\n", ConfigCodeString[CODE_INDEX]);
|
LogInfo("Config code = [ %s ]\n", ConfigCodeString[CODE_INDEX]);
|
||||||
return ConfigCodeString[CODE_INDEX];
|
return ConfigCodeString[CODE_INDEX];
|
||||||
}
|
}
|
||||||
LogError("Config code undefine.\n");
|
LogError("Config code undefine.\n");
|
||||||
return "Config code undefine.\n";
|
return "Config code undefine.\n";
|
||||||
}
|
}
|
||||||
static const bool CodeEqual(const StatusCode code, const char *value)
|
static const bool CodeEqual(const StatusCode code, const char *value)
|
||||||
{
|
{
|
||||||
if (memcmp(value, ConfigCodeString[code.mStatusCode - STATUS_CODE_END], strlen(value)) == 0) {
|
if (memcmp(value, ConfigCodeString[code.mStatusCode - STATUS_CODE_END], strlen(value)) == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
static StatusCode NewConfigCode(const long int code)
|
static StatusCode NewConfigCode(const long int code)
|
||||||
{
|
{
|
||||||
StatusCode result = {PrintStringConfigCode, CodeEqual, code};
|
StatusCode result = {PrintStringConfigCode, CodeEqual, code};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
const StatusCode CreateConfigCode(const long int code)
|
const StatusCode CreateConfigCode(const long int code)
|
||||||
{
|
{
|
||||||
// if (STATUS_CODE_OK <= code && code < STATUS_CODE_END)
|
// if (STATUS_CODE_OK <= code && code < STATUS_CODE_END)
|
||||||
// {
|
// {
|
||||||
// return CreateStatusCode(code);
|
// return CreateStatusCode(code);
|
||||||
// }
|
// }
|
||||||
if (STATUS_CODE_END <= code && code < CONFIG_CODE_END) {
|
if (STATUS_CODE_END <= code && code < CONFIG_CODE_END) {
|
||||||
return NewConfigCode(code);
|
return NewConfigCode(code);
|
||||||
}
|
}
|
||||||
LogError("undefined code.\n");
|
LogError("undefined code.\n");
|
||||||
return CreateStatusCode(STATUS_CODE_END);
|
return CreateStatusCode(STATUS_CODE_END);
|
||||||
}
|
}
|
|
@ -1,29 +1,35 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 Fancy Code.
|
* Copyright (c) 2023 Fancy Code.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef CONFIG_BASE_CODE_H
|
//Copyright Statement and License: The beginning of the file contains a copyright statement and license information, indicating that this code is copyrighted by Fancy Code and follows the terms of Apache License, Version 2.0. This means that using this code must comply with the Apache 2.0 license regulations
|
||||||
#define CONFIG_BASE_CODE_H
|
#ifndef CONFIG_BASE_CODE_H
|
||||||
#include "ConfigBase.h"
|
#define CONFIG_BASE_CODE_H
|
||||||
#include "StatusCode.h"
|
//#The three pieces of code, ifndef CONFIG_SBASE-CEDE.H, # define CONFIG_SBASE-CEDE.H, and # endif, are standard header file protectors (also known as inclusion guards) used to prevent header files from being duplicated.
|
||||||
#ifdef __cplusplus
|
#include "ConfigBase.h"
|
||||||
extern "C" {
|
#include "StatusCode.h"
|
||||||
#endif
|
//These two lines of code contain two other header files that may define the Config Base class and Status Code enumeration or class, which will be used in the current header file.
|
||||||
#ifndef CONFIG_OWNER
|
#ifdef __cplusplus
|
||||||
#error This is internal file, never include it.
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
const StatusCode CreateConfigCode(const long int code);
|
//It is to ensure that the code written in C language can be linked and used correctly when used in the C++environment. Extern "C" tells the C++compiler that this part of the code should be compiled and linked according to the rules of the C language to avoid the problem of name mangling in C++.
|
||||||
#ifdef __cplusplus
|
#ifndef CONFIG_OWNER
|
||||||
}
|
#error This is internal file, never include it.
|
||||||
#endif
|
// These two lines of code are a compile time check. If the VNet OWNER macro is not defined, the compiler will report an error and display the message 'This is internal file, never include it.'. This is usually used to prevent this header file from being directly included externally, possibly because it contains some definitions or declarations that should only be used internally within the library.
|
||||||
#endif
|
#endif
|
||||||
|
const StatusCode CreateConfigCode(const long int code);// This line of code declares a function called CreateConfig Code, which takes a parameter code of type long int and returns a value of type Status Code. This function may be used to create a configuration object or perform a configuration operation based on a given code (possibly some configuration identifier), and return a status code to indicate the success or failure of the operation.
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
//In summary, this header file defines a function declaration related to the configuration code, and ensures the correctness and security of the code through a series of conditional compilations and header file protectors.
|
|
@ -1,347 +1,347 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 Fancy Code.
|
* Copyright (c) 2023 Fancy Code.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "ConfigBaseImpl.h"
|
#include "ConfigBaseImpl.h"
|
||||||
#include "ConfigBase.h"
|
#include "ConfigBase.h"
|
||||||
#include "ConfigBaseCode.h"
|
#include "ConfigBaseCode.h"
|
||||||
#include "ILog.h"
|
#include "ILog.h"
|
||||||
#include "StatusCode.h"
|
#include "StatusCode.h"
|
||||||
#include <libconfig.h>
|
#include <libconfig.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
constexpr int INVALID_RESULT = -1;
|
constexpr int INVALID_RESULT = -1;
|
||||||
#define CHECK_SHORT_LIMIT(value) (value > SHRT_MAX ? false : (value < SHRT_MIN ? false : true))
|
#define CHECK_SHORT_LIMIT(value) (value > SHRT_MAX ? false : (value < SHRT_MIN ? false : true))
|
||||||
#define CHECK_LONG_LIMIT(value) (value > LONG_MAX ? false : (value < LONG_MIN ? false : true))
|
#define CHECK_LONG_LIMIT(value) (value > LONG_MAX ? false : (value < LONG_MIN ? false : true))
|
||||||
#define CHECK_CHAR_LIMIT(value) (value > CHAR_MAX ? false : (value < CHAR_MIN ? false : true))
|
#define CHECK_CHAR_LIMIT(value) (value > CHAR_MAX ? false : (value < CHAR_MIN ? false : true))
|
||||||
#define CHECK_FLOAT_LIMIT(value) (fabs(value - ((float)value)) < 0.000001 ? false : true)
|
#define CHECK_FLOAT_LIMIT(value) (fabs(value - ((float)value)) < 0.000001 ? false : true)
|
||||||
|
|
||||||
ConfigBaseImpl::ConfigBaseImpl(const std::string &fileName) : mFileName(fileName)
|
ConfigBaseImpl::ConfigBaseImpl(const std::string &fileName) : mFileName(fileName)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
bool ConfigBaseImpl::OpenConfigFile(void)
|
bool ConfigBaseImpl::OpenConfigFile(void)
|
||||||
{
|
{
|
||||||
config_init(&mCfg);
|
config_init(&mCfg);
|
||||||
config_set_options(&mCfg,
|
config_set_options(&mCfg,
|
||||||
(CONFIG_OPTION_FSYNC | CONFIG_OPTION_SEMICOLON_SEPARATORS |
|
(CONFIG_OPTION_FSYNC | CONFIG_OPTION_SEMICOLON_SEPARATORS |
|
||||||
CONFIG_OPTION_COLON_ASSIGNMENT_FOR_GROUPS | CONFIG_OPTION_OPEN_BRACE_ON_SEPARATE_LINE));
|
CONFIG_OPTION_COLON_ASSIGNMENT_FOR_GROUPS | CONFIG_OPTION_OPEN_BRACE_ON_SEPARATE_LINE));
|
||||||
constexpr int FIEL_EXIST = 0;
|
constexpr int FIEL_EXIST = 0;
|
||||||
if (FIEL_EXIST == access(mFileName.c_str(), F_OK)) {
|
if (FIEL_EXIST == access(mFileName.c_str(), F_OK)) {
|
||||||
if (!config_read_file(&mCfg, mFileName.c_str())) {
|
if (!config_read_file(&mCfg, mFileName.c_str())) {
|
||||||
LogError("Read file failed[%s].\n", mFileName.c_str());
|
LogError("Read file failed[%s].\n", mFileName.c_str());
|
||||||
fprintf(
|
fprintf(
|
||||||
stderr, "%s:%d - %s\n", config_error_file(&mCfg), config_error_line(&mCfg), config_error_text(&mCfg));
|
stderr, "%s:%d - %s\n", config_error_file(&mCfg), config_error_line(&mCfg), config_error_text(&mCfg));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogInfo("Config file doesn't exist.mFileName = %s\n", mFileName.c_str());
|
LogInfo("Config file doesn't exist.mFileName = %s\n", mFileName.c_str());
|
||||||
/* Write out the new configuration. */
|
/* Write out the new configuration. */
|
||||||
if (!config_write_file(&mCfg, mFileName.c_str())) {
|
if (!config_write_file(&mCfg, mFileName.c_str())) {
|
||||||
fprintf(stderr, "Error while writing file.\n");
|
fprintf(stderr, "Error while writing file.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void ConfigBaseImpl::CloseConfigFile(void)
|
void ConfigBaseImpl::CloseConfigFile(void)
|
||||||
{
|
{
|
||||||
config_destroy(&mCfg);
|
config_destroy(&mCfg);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigSaveFile(void)
|
StatusCode ConfigBaseImpl::ConfigSaveFile(void)
|
||||||
{
|
{
|
||||||
LogInfo("Save file[%s].\n", mFileName.c_str());
|
LogInfo("Save file[%s].\n", mFileName.c_str());
|
||||||
if (!config_write_file(&mCfg, mFileName.c_str())) {
|
if (!config_write_file(&mCfg, mFileName.c_str())) {
|
||||||
LogError("Save config failed.\n");
|
LogError("Save config failed.\n");
|
||||||
return CreateStatusCode(STATUS_CODE_NOT_OK);
|
return CreateStatusCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigGetInt(const char *name, int *value)
|
StatusCode ConfigBaseImpl::ConfigGetInt(const char *name, int *value)
|
||||||
{
|
{
|
||||||
int result = INVALID_RESULT;
|
int result = INVALID_RESULT;
|
||||||
result = config_lookup_int(&mCfg, name, value);
|
result = config_lookup_int(&mCfg, name, value);
|
||||||
if (CONFIG_FALSE == result) {
|
if (CONFIG_FALSE == result) {
|
||||||
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigSetInt(const char *name, const int value)
|
StatusCode ConfigBaseImpl::ConfigSetInt(const char *name, const int value)
|
||||||
{
|
{
|
||||||
config_setting_t *root = nullptr;
|
config_setting_t *root = nullptr;
|
||||||
config_setting_t *setting = nullptr;
|
config_setting_t *setting = nullptr;
|
||||||
root = config_root_setting(&mCfg);
|
root = config_root_setting(&mCfg);
|
||||||
if (nullptr == root) {
|
if (nullptr == root) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
setting = config_setting_get_member(root, name);
|
setting = config_setting_get_member(root, name);
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
setting = config_setting_add(root, name, CONFIG_TYPE_INT);
|
setting = config_setting_add(root, name, CONFIG_TYPE_INT);
|
||||||
}
|
}
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
config_setting_set_int(setting, value);
|
config_setting_set_int(setting, value);
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigGetShort(const char *name, short *value)
|
StatusCode ConfigBaseImpl::ConfigGetShort(const char *name, short *value)
|
||||||
{
|
{
|
||||||
int intValue = 0;
|
int intValue = 0;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
result = config_lookup_int(&mCfg, name, &intValue);
|
result = config_lookup_int(&mCfg, name, &intValue);
|
||||||
if (CONFIG_FALSE == result || CHECK_SHORT_LIMIT(intValue)) {
|
if (CONFIG_FALSE == result || CHECK_SHORT_LIMIT(intValue)) {
|
||||||
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
||||||
}
|
}
|
||||||
*value = (short)intValue;
|
*value = (short)intValue;
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigSetShort(const char *name, const short value)
|
StatusCode ConfigBaseImpl::ConfigSetShort(const char *name, const short value)
|
||||||
{
|
{
|
||||||
config_setting_t *root = nullptr;
|
config_setting_t *root = nullptr;
|
||||||
config_setting_t *setting = nullptr;
|
config_setting_t *setting = nullptr;
|
||||||
root = config_root_setting(&mCfg);
|
root = config_root_setting(&mCfg);
|
||||||
if (nullptr == root) {
|
if (nullptr == root) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
setting = config_setting_get_member(root, name);
|
setting = config_setting_get_member(root, name);
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
setting = config_setting_add(root, name, CONFIG_TYPE_INT);
|
setting = config_setting_add(root, name, CONFIG_TYPE_INT);
|
||||||
}
|
}
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
int intValue = value;
|
int intValue = value;
|
||||||
config_setting_set_int(setting, intValue);
|
config_setting_set_int(setting, intValue);
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigGetLong(const char *name, long *value)
|
StatusCode ConfigBaseImpl::ConfigGetLong(const char *name, long *value)
|
||||||
{
|
{
|
||||||
long long llongValue = 0;
|
long long llongValue = 0;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
result = config_lookup_int64(&mCfg, name, &llongValue);
|
result = config_lookup_int64(&mCfg, name, &llongValue);
|
||||||
if (CONFIG_FALSE == result || CHECK_LONG_LIMIT(llongValue)) {
|
if (CONFIG_FALSE == result || CHECK_LONG_LIMIT(llongValue)) {
|
||||||
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
||||||
}
|
}
|
||||||
*value = (long)llongValue;
|
*value = (long)llongValue;
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigSetLong(const char *name, const long value)
|
StatusCode ConfigBaseImpl::ConfigSetLong(const char *name, const long value)
|
||||||
{
|
{
|
||||||
config_setting_t *root = nullptr;
|
config_setting_t *root = nullptr;
|
||||||
config_setting_t *setting = nullptr;
|
config_setting_t *setting = nullptr;
|
||||||
root = config_root_setting(&mCfg);
|
root = config_root_setting(&mCfg);
|
||||||
if (nullptr == root) {
|
if (nullptr == root) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
setting = config_setting_get_member(root, name);
|
setting = config_setting_get_member(root, name);
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
setting = config_setting_add(root, name, CONFIG_TYPE_INT64);
|
setting = config_setting_add(root, name, CONFIG_TYPE_INT64);
|
||||||
}
|
}
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
long long llongValue = value;
|
long long llongValue = value;
|
||||||
config_setting_set_int64(setting, llongValue);
|
config_setting_set_int64(setting, llongValue);
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigGetLLong(const char *name, long long *value)
|
StatusCode ConfigBaseImpl::ConfigGetLLong(const char *name, long long *value)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
result = config_lookup_int64(&mCfg, name, value);
|
result = config_lookup_int64(&mCfg, name, value);
|
||||||
if (CONFIG_FALSE == result) {
|
if (CONFIG_FALSE == result) {
|
||||||
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigSetLLong(const char *name, const long long value)
|
StatusCode ConfigBaseImpl::ConfigSetLLong(const char *name, const long long value)
|
||||||
{
|
{
|
||||||
config_setting_t *root = nullptr;
|
config_setting_t *root = nullptr;
|
||||||
config_setting_t *setting = nullptr;
|
config_setting_t *setting = nullptr;
|
||||||
root = config_root_setting(&mCfg);
|
root = config_root_setting(&mCfg);
|
||||||
if (nullptr == root) {
|
if (nullptr == root) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
setting = config_setting_get_member(root, name);
|
setting = config_setting_get_member(root, name);
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
setting = config_setting_add(root, name, CONFIG_TYPE_INT64);
|
setting = config_setting_add(root, name, CONFIG_TYPE_INT64);
|
||||||
}
|
}
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
config_setting_set_int64(setting, value);
|
config_setting_set_int64(setting, value);
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigGetChar(const char *name, char *value)
|
StatusCode ConfigBaseImpl::ConfigGetChar(const char *name, char *value)
|
||||||
{
|
{
|
||||||
int charValue = 0;
|
int charValue = 0;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
result = config_lookup_int(&mCfg, name, &charValue);
|
result = config_lookup_int(&mCfg, name, &charValue);
|
||||||
if (CONFIG_FALSE == result && CHECK_CHAR_LIMIT(charValue)) {
|
if (CONFIG_FALSE == result && CHECK_CHAR_LIMIT(charValue)) {
|
||||||
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
||||||
}
|
}
|
||||||
*value = (char)charValue;
|
*value = (char)charValue;
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigSetChar(const char *name, const char value)
|
StatusCode ConfigBaseImpl::ConfigSetChar(const char *name, const char value)
|
||||||
{
|
{
|
||||||
config_setting_t *root = nullptr;
|
config_setting_t *root = nullptr;
|
||||||
config_setting_t *setting = nullptr;
|
config_setting_t *setting = nullptr;
|
||||||
root = config_root_setting(&mCfg);
|
root = config_root_setting(&mCfg);
|
||||||
if (nullptr == root) {
|
if (nullptr == root) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
setting = config_setting_get_member(root, name);
|
setting = config_setting_get_member(root, name);
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
setting = config_setting_add(root, name, CONFIG_TYPE_INT);
|
setting = config_setting_add(root, name, CONFIG_TYPE_INT);
|
||||||
}
|
}
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
int charValue = (int)value;
|
int charValue = (int)value;
|
||||||
config_setting_set_int(setting, charValue);
|
config_setting_set_int(setting, charValue);
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigGetBool(const char *name, bool *value)
|
StatusCode ConfigBaseImpl::ConfigGetBool(const char *name, bool *value)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
result = config_lookup_bool(&mCfg, name, (int *)value);
|
result = config_lookup_bool(&mCfg, name, (int *)value);
|
||||||
if (CONFIG_FALSE == result) {
|
if (CONFIG_FALSE == result) {
|
||||||
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigSetBool(const char *name, const bool value)
|
StatusCode ConfigBaseImpl::ConfigSetBool(const char *name, const bool value)
|
||||||
{
|
{
|
||||||
config_setting_t *root = nullptr;
|
config_setting_t *root = nullptr;
|
||||||
config_setting_t *setting = nullptr;
|
config_setting_t *setting = nullptr;
|
||||||
root = config_root_setting(&mCfg);
|
root = config_root_setting(&mCfg);
|
||||||
if (nullptr == root) {
|
if (nullptr == root) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
setting = config_setting_get_member(root, name);
|
setting = config_setting_get_member(root, name);
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
setting = config_setting_add(root, name, CONFIG_TYPE_BOOL);
|
setting = config_setting_add(root, name, CONFIG_TYPE_BOOL);
|
||||||
}
|
}
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
config_setting_set_bool(setting, (int)value);
|
config_setting_set_bool(setting, (int)value);
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigGetFloat(const char *name, float *value)
|
StatusCode ConfigBaseImpl::ConfigGetFloat(const char *name, float *value)
|
||||||
{
|
{
|
||||||
double dValue = 0;
|
double dValue = 0;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
result = config_lookup_float(&mCfg, name, &dValue);
|
result = config_lookup_float(&mCfg, name, &dValue);
|
||||||
if (CONFIG_FALSE == result || CHECK_FLOAT_LIMIT(dValue)) {
|
if (CONFIG_FALSE == result || CHECK_FLOAT_LIMIT(dValue)) {
|
||||||
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
||||||
}
|
}
|
||||||
*value = (float)dValue;
|
*value = (float)dValue;
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigSetFloat(const char *name, const float value)
|
StatusCode ConfigBaseImpl::ConfigSetFloat(const char *name, const float value)
|
||||||
{
|
{
|
||||||
config_setting_t *root = nullptr;
|
config_setting_t *root = nullptr;
|
||||||
config_setting_t *setting = nullptr;
|
config_setting_t *setting = nullptr;
|
||||||
root = config_root_setting(&mCfg);
|
root = config_root_setting(&mCfg);
|
||||||
if (nullptr == root) {
|
if (nullptr == root) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
setting = config_setting_get_member(root, name);
|
setting = config_setting_get_member(root, name);
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
setting = config_setting_add(root, name, CONFIG_TYPE_FLOAT);
|
setting = config_setting_add(root, name, CONFIG_TYPE_FLOAT);
|
||||||
}
|
}
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
double dValue = value;
|
double dValue = value;
|
||||||
config_setting_set_float(setting, dValue);
|
config_setting_set_float(setting, dValue);
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigGetDouble(const char *name, double *value)
|
StatusCode ConfigBaseImpl::ConfigGetDouble(const char *name, double *value)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
result = config_lookup_float(&mCfg, name, value);
|
result = config_lookup_float(&mCfg, name, value);
|
||||||
if (CONFIG_FALSE == result) {
|
if (CONFIG_FALSE == result) {
|
||||||
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigSetDouble(const char *name, const double value)
|
StatusCode ConfigBaseImpl::ConfigSetDouble(const char *name, const double value)
|
||||||
{
|
{
|
||||||
config_setting_t *root = nullptr;
|
config_setting_t *root = nullptr;
|
||||||
config_setting_t *setting = nullptr;
|
config_setting_t *setting = nullptr;
|
||||||
root = config_root_setting(&mCfg);
|
root = config_root_setting(&mCfg);
|
||||||
if (nullptr == root) {
|
if (nullptr == root) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
setting = config_setting_get_member(root, name);
|
setting = config_setting_get_member(root, name);
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
setting = config_setting_add(root, name, CONFIG_TYPE_FLOAT);
|
setting = config_setting_add(root, name, CONFIG_TYPE_FLOAT);
|
||||||
}
|
}
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
config_setting_set_float(setting, value);
|
config_setting_set_float(setting, value);
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigGetString(const char *name, const char **value)
|
StatusCode ConfigBaseImpl::ConfigGetString(const char *name, const char **value)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
result = config_lookup_string(&mCfg, name, value);
|
result = config_lookup_string(&mCfg, name, value);
|
||||||
if (CONFIG_FALSE == result) {
|
if (CONFIG_FALSE == result) {
|
||||||
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST);
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
StatusCode ConfigBaseImpl::ConfigSetString(const char *name, const char *value)
|
StatusCode ConfigBaseImpl::ConfigSetString(const char *name, const char *value)
|
||||||
{
|
{
|
||||||
config_setting_t *root = nullptr;
|
config_setting_t *root = nullptr;
|
||||||
config_setting_t *setting = nullptr;
|
config_setting_t *setting = nullptr;
|
||||||
root = config_root_setting(&mCfg);
|
root = config_root_setting(&mCfg);
|
||||||
if (nullptr == root) {
|
if (nullptr == root) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
setting = config_setting_get_member(root, name);
|
setting = config_setting_get_member(root, name);
|
||||||
if (!setting) {
|
if (!setting) {
|
||||||
setting = config_setting_add(root, name, CONFIG_TYPE_STRING);
|
setting = config_setting_add(root, name, CONFIG_TYPE_STRING);
|
||||||
}
|
}
|
||||||
if (nullptr == setting) {
|
if (nullptr == setting) {
|
||||||
LogError("Config function failed.\n");
|
LogError("Config function failed.\n");
|
||||||
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
return CreateConfigCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
config_setting_set_string(setting, value);
|
config_setting_set_string(setting, value);
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
|
@ -1,50 +1,53 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 Fancy Code.
|
* Copyright (c) 2023 Fancy Code.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef CONFIG_BASE_IMPL_H
|
#ifndef CONFIG_BASE_IMPL_H
|
||||||
#define CONFIG_BASE_IMPL_H
|
#define CONFIG_BASE_IMPL_H
|
||||||
#include "IConfigBase.h"
|
//Standard header file protection is used to prevent duplicate header files from being included.
|
||||||
#include <libconfig.h>
|
#include "IConfigBase.h"//This is an interface definition file, and the Config Base Impl class implements all the pure virtual functions declared in this interface.
|
||||||
class ConfigBaseImpl : public IConfigBase
|
#include <libconfig.h>//This is the header file of the libconfig library, which provides an API for handling configuration files.
|
||||||
{
|
#include <string>//String processing class in the C++standard library.
|
||||||
public:
|
class ConfigBaseImpl : public IConfigBase//The Config Base Impl class inherits from the FHIR figBase interface, which means it needs to implement all the pure virtual functions declared in the interface.
|
||||||
ConfigBaseImpl(const std::string &fileName);
|
{
|
||||||
virtual ~ConfigBaseImpl() = default;
|
public:
|
||||||
bool OpenConfigFile(void) override;
|
ConfigBaseImpl(const std::string &fileName);
|
||||||
void CloseConfigFile(void) override;
|
virtual ~ConfigBaseImpl() = default;
|
||||||
StatusCode ConfigSaveFile(void) override;
|
bool OpenConfigFile(void) override;//Open configuration file
|
||||||
StatusCode ConfigGetInt(const char *name, int *value) override;
|
void CloseConfigFile(void) override;//Close configuration file
|
||||||
StatusCode ConfigSetInt(const char *name, const int value) override;
|
StatusCode ConfigSaveFile(void) override;//Used to save configuration changes back to a file, but the return type is Status Code
|
||||||
StatusCode ConfigGetShort(const char *name, short *value) override;
|
StatusCode ConfigGetInt(const char *name, int *value) override;
|
||||||
StatusCode ConfigSetShort(const char *name, const short value) override;
|
StatusCode ConfigSetInt(const char *name, const int value) override;
|
||||||
StatusCode ConfigGetLong(const char *name, long *value) override;
|
StatusCode ConfigGetShort(const char *name, short *value) override;
|
||||||
StatusCode ConfigSetLong(const char *name, const long value) override;
|
StatusCode ConfigSetShort(const char *name, const short value) override;
|
||||||
StatusCode ConfigGetLLong(const char *name, long long *value) override;
|
StatusCode ConfigGetLong(const char *name, long *value) override;
|
||||||
StatusCode ConfigSetLLong(const char *name, const long long value) override;
|
StatusCode ConfigSetLong(const char *name, const long value) override;
|
||||||
StatusCode ConfigGetChar(const char *name, char *value) override;
|
StatusCode ConfigGetLLong(const char *name, long long *value) override;
|
||||||
StatusCode ConfigSetChar(const char *name, const char value) override;
|
StatusCode ConfigSetLLong(const char *name, const long long value) override;
|
||||||
StatusCode ConfigGetBool(const char *name, bool *value) override;
|
StatusCode ConfigGetChar(const char *name, char *value) override;
|
||||||
StatusCode ConfigSetBool(const char *name, const bool value) override;
|
StatusCode ConfigSetChar(const char *name, const char value) override;
|
||||||
StatusCode ConfigGetFloat(const char *name, float *value) override;
|
StatusCode ConfigGetBool(const char *name, bool *value) override;
|
||||||
StatusCode ConfigSetFloat(const char *name, const float value) override;
|
StatusCode ConfigSetBool(const char *name, const bool value) override;
|
||||||
StatusCode ConfigGetDouble(const char *name, double *value) override;
|
StatusCode ConfigGetFloat(const char *name, float *value) override;
|
||||||
StatusCode ConfigSetDouble(const char *name, const double value) override;
|
StatusCode ConfigSetFloat(const char *name, const float value) override;
|
||||||
StatusCode ConfigGetString(const char *name, const char **value) override;
|
StatusCode ConfigGetDouble(const char *name, double *value) override;
|
||||||
StatusCode ConfigSetString(const char *name, const char *value) override;
|
StatusCode ConfigSetDouble(const char *name, const double value) override;
|
||||||
|
StatusCode ConfigGetString(const char *name, const char **value) override;
|
||||||
private:
|
StatusCode ConfigSetString(const char *name, const char *value) override;
|
||||||
const std::string mFileName;
|
//These functions provide interfaces for obtaining and setting various data types (such as integers, floating-point numbers, strings, etc.) from configuration files. They accept the name of a configuration item and a pointer to the value (for Get functions) or the value itself (for Set functions), and return a Status Code representing the operation result.
|
||||||
config_t mCfg;
|
private:
|
||||||
};
|
const std::string mFileName;// The path to store configuration files.
|
||||||
#endif
|
config_t mCfg;//The confic_t type in the libconfig library is used to represent the internal structure of configuration files.
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
//In summary, this code defines a class for handling configuration files that provides rich interfaces to read and modify configuration items in the configuration file, achieved through the use of the libconfig library.
|
|
@ -1,123 +1,123 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 Fancy Code.
|
* Copyright (c) 2023 Fancy Code.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "IConfigBase.h"
|
#include "IConfigBase.h"
|
||||||
#include "ConfigBaseImpl.h"
|
#include "ConfigBaseImpl.h"
|
||||||
#include "ILog.h"
|
#include "ILog.h"
|
||||||
#include "StatusCode.h"
|
#include "StatusCode.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
bool IConfigBase::OpenConfigFile(void)
|
bool IConfigBase::OpenConfigFile(void)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void IConfigBase::CloseConfigFile(void)
|
void IConfigBase::CloseConfigFile(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigSaveFile(void)
|
StatusCode IConfigBase::ConfigSaveFile(void)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigGetInt(const char *name, int *value)
|
StatusCode IConfigBase::ConfigGetInt(const char *name, int *value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigSetInt(const char *name, const int value)
|
StatusCode IConfigBase::ConfigSetInt(const char *name, const int value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigGetShort(const char *name, short *value)
|
StatusCode IConfigBase::ConfigGetShort(const char *name, short *value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigSetShort(const char *name, const short value)
|
StatusCode IConfigBase::ConfigSetShort(const char *name, const short value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigGetLong(const char *name, long *value)
|
StatusCode IConfigBase::ConfigGetLong(const char *name, long *value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigSetLong(const char *name, const long value)
|
StatusCode IConfigBase::ConfigSetLong(const char *name, const long value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigGetLLong(const char *name, long long *value)
|
StatusCode IConfigBase::ConfigGetLLong(const char *name, long long *value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigSetLLong(const char *name, const long long value)
|
StatusCode IConfigBase::ConfigSetLLong(const char *name, const long long value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigGetChar(const char *name, char *value)
|
StatusCode IConfigBase::ConfigGetChar(const char *name, char *value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigSetChar(const char *name, const char value)
|
StatusCode IConfigBase::ConfigSetChar(const char *name, const char value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigGetBool(const char *name, bool *value)
|
StatusCode IConfigBase::ConfigGetBool(const char *name, bool *value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigSetBool(const char *name, const bool value)
|
StatusCode IConfigBase::ConfigSetBool(const char *name, const bool value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigGetFloat(const char *name, float *value)
|
StatusCode IConfigBase::ConfigGetFloat(const char *name, float *value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigSetFloat(const char *name, const float value)
|
StatusCode IConfigBase::ConfigSetFloat(const char *name, const float value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigGetDouble(const char *name, double *value)
|
StatusCode IConfigBase::ConfigGetDouble(const char *name, double *value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigSetDouble(const char *name, const double value)
|
StatusCode IConfigBase::ConfigSetDouble(const char *name, const double value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigGetString(const char *name, const char **value)
|
StatusCode IConfigBase::ConfigGetString(const char *name, const char **value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
StatusCode IConfigBase::ConfigSetString(const char *name, const char *value)
|
StatusCode IConfigBase::ConfigSetString(const char *name, const char *value)
|
||||||
{
|
{
|
||||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
}
|
}
|
||||||
static const char *CONFIG_BASE_NAME = "config_base";
|
static const char *CONFIG_BASE_NAME = "config_base";
|
||||||
const char *GetConfigBaseModuleName(void)
|
const char *GetConfigBaseModuleName(void)
|
||||||
{
|
{
|
||||||
return CONFIG_BASE_NAME;
|
return CONFIG_BASE_NAME;
|
||||||
}
|
}
|
||||||
std::shared_ptr<IConfigBase> *NewConfigBase(const char *fileName)
|
std::shared_ptr<IConfigBase> *NewConfigBase(const char *fileName)
|
||||||
{
|
{
|
||||||
LogInfo("Create the config base object.\n");
|
LogInfo("Create the config base object.\n");
|
||||||
ConfigBase *impl = (ConfigBase *)malloc(sizeof(ConfigBase));
|
ConfigBase *impl = (ConfigBase *)malloc(sizeof(ConfigBase));
|
||||||
if (nullptr == impl) {
|
if (nullptr == impl) {
|
||||||
LogError("NewConfigBase::malloc failed.\n");
|
LogError("NewConfigBase::malloc failed.\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ConfigBase tmp;
|
ConfigBase tmp;
|
||||||
memcpy((void *)impl, (void *)&tmp, sizeof(ConfigBase));
|
memcpy((void *)impl, (void *)&tmp, sizeof(ConfigBase));
|
||||||
impl->mHeader.mCheckName = CONFIG_BASE_NAME;
|
impl->mHeader.mCheckName = CONFIG_BASE_NAME;
|
||||||
impl->mIConfigBase = std::make_shared<ConfigBaseImpl>(fileName);
|
impl->mIConfigBase = std::make_shared<ConfigBaseImpl>(fileName);
|
||||||
return (std::shared_ptr<IConfigBase> *)(((char *)impl) + sizeof(IConfigBaseHeader));
|
return (std::shared_ptr<IConfigBase> *)(((char *)impl) + sizeof(IConfigBaseHeader));
|
||||||
}
|
}
|
|
@ -1,57 +1,62 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 Fancy Code.
|
* Copyright (c) 2023 Fancy Code.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef I_CONFIG_BASE_H
|
#ifndef I_CONFIG_BASE_H
|
||||||
#define I_CONFIG_BASE_H
|
#define I_CONFIG_BASE_H
|
||||||
#include "StatusCode.h"
|
//Header file protection (preventing header files from being duplicated).
|
||||||
#include <memory>
|
#include "StatusCode.h"
|
||||||
class IConfigBase
|
#include <memory>
|
||||||
{
|
//Status Code. h (which may be a file that defines a status code enumeration or class to indicate the status of successful or failed operations) and<memory>(a part of the C++standard library that provides memory management features such as smart pointers).
|
||||||
public:
|
class IConfigBase// FHIR gBase interface
|
||||||
IConfigBase() = default;
|
{
|
||||||
virtual ~IConfigBase() = default;
|
public:
|
||||||
virtual bool OpenConfigFile(void);
|
IConfigBase() = default;
|
||||||
virtual void CloseConfigFile(void);
|
virtual ~IConfigBase() = default;
|
||||||
virtual StatusCode ConfigSaveFile(void);
|
virtual bool OpenConfigFile(void);
|
||||||
virtual StatusCode ConfigGetInt(const char *name, int *value);
|
virtual void CloseConfigFile(void);
|
||||||
virtual StatusCode ConfigSetInt(const char *name, const int value);
|
virtual StatusCode ConfigSaveFile(void);
|
||||||
virtual StatusCode ConfigGetShort(const char *name, short *value);
|
virtual StatusCode ConfigGetInt(const char *name, int *value);
|
||||||
virtual StatusCode ConfigSetShort(const char *name, const short value);
|
virtual StatusCode ConfigSetInt(const char *name, const int value);
|
||||||
virtual StatusCode ConfigGetLong(const char *name, long *value);
|
virtual StatusCode ConfigGetShort(const char *name, short *value);
|
||||||
virtual StatusCode ConfigSetLong(const char *name, const long value);
|
virtual StatusCode ConfigSetShort(const char *name, const short value);
|
||||||
virtual StatusCode ConfigGetLLong(const char *name, long long *value);
|
virtual StatusCode ConfigGetLong(const char *name, long *value);
|
||||||
virtual StatusCode ConfigSetLLong(const char *name, const long long value);
|
virtual StatusCode ConfigSetLong(const char *name, const long value);
|
||||||
virtual StatusCode ConfigGetChar(const char *name, char *value);
|
virtual StatusCode ConfigGetLLong(const char *name, long long *value);
|
||||||
virtual StatusCode ConfigSetChar(const char *name, const char value);
|
virtual StatusCode ConfigSetLLong(const char *name, const long long value);
|
||||||
virtual StatusCode ConfigGetBool(const char *name, bool *value);
|
virtual StatusCode ConfigGetChar(const char *name, char *value);
|
||||||
virtual StatusCode ConfigSetBool(const char *name, const bool value);
|
virtual StatusCode ConfigSetChar(const char *name, const char value);
|
||||||
virtual StatusCode ConfigGetFloat(const char *name, float *value);
|
virtual StatusCode ConfigGetBool(const char *name, bool *value);
|
||||||
virtual StatusCode ConfigSetFloat(const char *name, const float value);
|
virtual StatusCode ConfigSetBool(const char *name, const bool value);
|
||||||
virtual StatusCode ConfigGetDouble(const char *name, double *value);
|
virtual StatusCode ConfigGetFloat(const char *name, float *value);
|
||||||
virtual StatusCode ConfigSetDouble(const char *name, const double value);
|
virtual StatusCode ConfigSetFloat(const char *name, const float value);
|
||||||
virtual StatusCode ConfigGetString(const char *name, const char **value);
|
virtual StatusCode ConfigGetDouble(const char *name, double *value);
|
||||||
virtual StatusCode ConfigSetString(const char *name, const char *value);
|
virtual StatusCode ConfigSetDouble(const char *name, const double value);
|
||||||
};
|
virtual StatusCode ConfigGetString(const char *name, const char **value);
|
||||||
typedef struct i_config_base_header
|
virtual StatusCode ConfigSetString(const char *name, const char *value);
|
||||||
{
|
};
|
||||||
const char *mCheckName;
|
//IKON Base is an abstract base class that defines interfaces related to configuration management. It includes default implementations of constructors and destructors (i.e. do not perform any operations), as well as a series of virtual functions for opening and closing configuration files, saving configurations, and obtaining and setting configuration values for various data types. The specific implementation of these virtual functions will be provided by derived classes.
|
||||||
} IConfigBaseHeader;
|
typedef struct i_config_base_header//Defined a struct i_config.base_header containing a pointer mCheckName to a character, which may be used for some form of validation or recognition.
|
||||||
typedef struct config_base
|
{
|
||||||
{
|
const char *mCheckName;
|
||||||
IConfigBaseHeader mHeader;
|
} IConfigBaseHeader;
|
||||||
std::shared_ptr<IConfigBase> mIConfigBase;
|
typedef struct config_base//Defined a struct config.base that contains a member mHeader of type iKON figBaseHeader and a smart pointer mIConfig Base pointing to iKON figBase. This structure may be used to store and manage configuration instances in applications.
|
||||||
} ConfigBase;
|
{
|
||||||
const char *GetConfigBaseModuleName(void);
|
IConfigBaseHeader mHeader;
|
||||||
std::shared_ptr<IConfigBase> *NewConfigBase(const char *fileName);
|
std::shared_ptr<IConfigBase> mIConfigBase;
|
||||||
#endif
|
} ConfigBase;
|
||||||
|
const char *GetConfigBaseModuleName(void);
|
||||||
|
std::shared_ptr<IConfigBase> *NewConfigBase(const char *fileName);
|
||||||
|
//Declared two functions: FHIR nfigBaseModulus Name (which may be used to obtain the name of a configuration module) and NewConfig Base (which takes a file name as a parameter and returns a pointer to the FHIR figBase smart pointer for creating and returning a new configuration instance).
|
||||||
|
#endif
|
||||||
|
//This code defines a C++interface and related data structures for configuration management, as well as function declarations related to it. It utilizes the abstract base classes, virtual functions, smart pointers, and other features of C++to achieve flexible configuration management functionality.
|
|
@ -54,4 +54,24 @@ function(log_disable target)
|
||||||
PROPERTY COMPILE_DEFINITIONS ${defs})
|
PROPERTY COMPILE_DEFINITIONS ${defs})
|
||||||
endforeach()
|
endforeach()
|
||||||
endfunction()
|
endfunction()
|
||||||
```
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## 1.4. 各文件的作用
|
||||||
|
* **easyloggingpp**:在Log目录下发挥了日志记录、存储、管理的重要作用,为C++项目的开发和维护提供了强有力的支持。
|
||||||
|
|
||||||
|
* **lLogMakePtr.h**:提供了一个日志实例创建和管理的机制,可能是作为应用程序中日志系统的一部分。通过使用单例模式和虚函数,它允许在应用程序的不同部分之间共享和交换日志实现,同时保持对日志系统底层实现的抽象。
|
||||||
|
|
||||||
|
* **lLogMakePtr.cpp**: 提供了一个日志模块的创建和销毁机制,以及基于不同实现的日志对象的创建方法。
|
||||||
|
|
||||||
|
* **Log.h**: 提供了一个C语言兼容的日志接口,允许C或C++代码以统一的方式使用日志功能。
|
||||||
|
|
||||||
|
* **Log.cpp**: 提供了一个C兼容的日志接口实现,该实现基于C++的 ILogCpp 类来处理实际的日志记录。它允许C或C++代码使用统一的日志接口,而无需关心底层的日志实现细节。
|
||||||
|
|
||||||
|
* **LogEasylogging.h**: 为基于 Easylogging++ 的日志系统提供了一个C++接口实现。通过继承 ILogCpp 接口并实现其中的函数,它使得日志功能的使用者能够以一种统一和标准化的方式记录和管理日志,而无需关心底层的日志实现细节。
|
||||||
|
|
||||||
|
* **LogEasylogging.cpp**: 通过实现 LogEasylogging 类,为应用程序提供了一个基于 Easylogging++ 库的日志系统,支持不同级别的日志记录,并允许通过配置文件来定制日志的行为。
|
||||||
|
|
||||||
|
* **Loglmpl.h**: 提供了一个用于扩展和实现具体日志功能的基类,同时保持了与 ILogCpp 接口的兼容性。
|
||||||
|
|
||||||
|
* **Loglmpl.cpp**: 为空。
|
|
@ -16,6 +16,11 @@
|
||||||
#define ILOGCPP_H
|
#define ILOGCPP_H
|
||||||
#include "ILog.h"
|
#include "ILog.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
/**
|
||||||
|
* @brief Abstract interface class
|
||||||
|
* If you want to add additional functions, you can derive a class from it to
|
||||||
|
* meet the product requirements.
|
||||||
|
*/
|
||||||
class ILogCpp
|
class ILogCpp
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -12,6 +12,11 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a log instance
|
||||||
|
*
|
||||||
|
*/
|
||||||
#ifndef ILOG_MAKE_PTR_H
|
#ifndef ILOG_MAKE_PTR_H
|
||||||
#define ILOG_MAKE_PTR_H
|
#define ILOG_MAKE_PTR_H
|
||||||
#include "ILogCpp.h"
|
#include "ILogCpp.h"
|
||||||
|
|
|
@ -19,6 +19,12 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <easylogging++.h>
|
||||||
|
/**
|
||||||
|
* @brief jieshao
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
*/
|
||||||
static void LogFree(ILog *object)
|
static void LogFree(ILog *object)
|
||||||
{
|
{
|
||||||
printf("log instance free.\n");
|
printf("log instance free.\n");
|
||||||
|
@ -28,7 +34,24 @@ static void LogFree(ILog *object)
|
||||||
}
|
}
|
||||||
static int LogPrintf(ILog *object, const char *function, const int line, const enum LogType type, const char *format,
|
static int LogPrintf(ILog *object, const char *function, const int line, const enum LogType type, const char *format,
|
||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
|
el::Configurations defaultConf;
|
||||||
|
defaultConf.setToDefault();
|
||||||
|
|
||||||
|
defaultConf.set(el::Level::Info,
|
||||||
|
el::ConfigurationType::Format,
|
||||||
|
"\x1b[32m%datetime %level %msg\x1b[0m");
|
||||||
|
|
||||||
|
defaultConf.set(el::Level::Debug,
|
||||||
|
el::ConfigurationType::Format,
|
||||||
|
"\x1b[33m%datetime %level %msg\x1b[0m");
|
||||||
|
|
||||||
|
defaultConf.set(el::Level::Error,
|
||||||
|
el::ConfigurationType::Format,
|
||||||
|
"\x1b[31m%datetime %level %msg\x1b[0m");
|
||||||
|
|
||||||
|
el::Loggers::reconfigureLogger("default", defaultConf);
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// LogTypeToString(type);
|
// LogTypeToString(type);
|
||||||
constexpr int SEND_TRACE_BUFF_SIZE = 2048;
|
constexpr int SEND_TRACE_BUFF_SIZE = 2048;
|
||||||
|
|
|
@ -22,4 +22,4 @@
|
||||||
ENABLED = false
|
ENABLED = false
|
||||||
FILENAME = "/tmp/logs/myeasylog-configuration.cpp-error.log"
|
FILENAME = "/tmp/logs/myeasylog-configuration.cpp-error.log"
|
||||||
* FATAL:
|
* FATAL:
|
||||||
ENABLED = false
|
ENABLED = false
|
|
@ -19,6 +19,7 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
void *ICreateMediaBase(const MediaHandleType type)
|
void *ICreateMediaBase(const MediaHandleType type)
|
||||||
{
|
{
|
||||||
return NewIMediaBase(type);
|
return NewIMediaBase(type);
|
||||||
|
|
|
@ -81,7 +81,7 @@ add_custom_target(
|
||||||
curl
|
curl
|
||||||
DEPENDS openssl
|
DEPENDS openssl
|
||||||
COMMAND echo "Build curl. openssl path = ${EXTERNAL_SOURCE_PATH}"
|
COMMAND echo "Build curl. openssl path = ${EXTERNAL_SOURCE_PATH}"
|
||||||
COMMAND ./configure --without-zlib --prefix=${EXTERNAL_SOURCE_PATH}/curl --with-ssl=${EXTERNAL_SOURCE_PATH}/openssl/build ${CURL_HOST} CC=${CMAKE_C_COMPILER}
|
COMMAND ./configure --disable-shared --without-zlib --prefix=${EXTERNAL_SOURCE_PATH}/curl --with-ssl=${EXTERNAL_SOURCE_PATH}/openssl/build ${CURL_HOST} CC=${CMAKE_C_COMPILER}
|
||||||
COMMAND make
|
COMMAND make
|
||||||
COMMAND cp ${EXTERNAL_SOURCE_PATH}/curl/curl-8.1.2/lib/.libs/lib*.a ${LIBS_OUTPUT_PATH}
|
COMMAND cp ${EXTERNAL_SOURCE_PATH}/curl/curl-8.1.2/lib/.libs/lib*.a ${LIBS_OUTPUT_PATH}
|
||||||
COMMAND cp ${EXTERNAL_SOURCE_PATH}/openssl/build/lib/lib*.a ${LIBS_OUTPUT_PATH}
|
COMMAND cp ${EXTERNAL_SOURCE_PATH}/openssl/build/lib/lib*.a ${LIBS_OUTPUT_PATH}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#define TCP_MODULE_H
|
#define TCP_MODULE_H
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#define TCP_MODULE_WRITE_ERROR -1;
|
#define TCP_MODULE_WRITE_ERROR -1
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,15 +25,15 @@ typedef bool (*TcpAcceptClientFunction)(void *, const char *);
|
||||||
typedef void (*SocketClosedFunction)(const void *);
|
typedef void (*SocketClosedFunction)(const void *);
|
||||||
typedef struct client_accept_parm
|
typedef struct client_accept_parm
|
||||||
{
|
{
|
||||||
const TcpReadFunction mReadFunc;
|
const TcpReadFunction mReadFunc; ///< This function is defined in the test file
|
||||||
const SocketClosedFunction mClosedFunc;
|
const SocketClosedFunction mClosedFunc; ///< This function is defined in the test file.
|
||||||
} ClientAcceptParam;
|
} ClientAcceptParam;
|
||||||
typedef struct tcp_server_parm
|
typedef struct tcp_server_parm
|
||||||
{
|
{
|
||||||
const char *mIp;
|
const char *mIp; ///< Server ip
|
||||||
const int mPort;
|
const int mPort; ///< Server port
|
||||||
const TcpAcceptClientFunction mAcceptClientFunc;
|
const TcpAcceptClientFunction mAcceptClientFunc; ///< This function is defined in the test file.
|
||||||
const ClientAcceptParam mClientAcceptParam;
|
const ClientAcceptParam mClientAcceptParam; ///< This function is defined in the test file.
|
||||||
} TcpServerParam;
|
} TcpServerParam;
|
||||||
typedef struct tcp_parm
|
typedef struct tcp_parm
|
||||||
{
|
{
|
||||||
|
|
64
utils/TcpModule/readme.md
Normal file
64
utils/TcpModule/readme.md
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
# TCP模块
|
||||||
|
这个项目实现了一个用于网络通信的TCP模块,提供了服务器和客户端功能。
|
||||||
|
在网络编程中,套接字(socket)是一个用于网络通信的端点。在客户端和服务器模型中,客户端会创建一个套接字来与服务器建立连接,而服务器则监听来自客户端的连接请求。一旦连接建立,客户端和服务器就可以通过各自的套接字进行数据的发送和接收。
|
||||||
|
|
||||||
|
# 涉及的知识
|
||||||
|
* 网络通信
|
||||||
|
* 多线程处理
|
||||||
|
* 回调函数
|
||||||
|
* C++/C
|
||||||
|
* I/O多路复用
|
||||||
|
* 套接字编程
|
||||||
|
* TCP协议
|
||||||
|
* 事件循环
|
||||||
|
|
||||||
|
# 各文件的作用
|
||||||
|
* **TcpModule.h**:定义了TCP模块的公共接口和数据结构,包括服务器和客户端参数结构体、回调函数类型等。
|
||||||
|
|
||||||
|
* **TcpModule.cpp**:实现了TcpModule.h中定义的接口,包括创建和释放TCP服务器和客户端的函数。
|
||||||
|
|
||||||
|
* **ITcpClient.h/ITcpClient.cpp**:定义和实现了TCP客户端接口,包括初始化、读取数据、写入数据和关闭连接等虚函数。
|
||||||
|
|
||||||
|
* **ITcpServer.h/ITcpServer.cpp**:定义和实现了TCP服务器接口,包括初始化、关闭服务器等虚函数。
|
||||||
|
|
||||||
|
* **TcpClientImpl.h/TcpClientImpl.cpp**:实现了ITcpClient接口,是TCP客户端的具体实现。
|
||||||
|
|
||||||
|
* **TcpServerImpl.h/TcpServerImpl.cpp**:实现了ITcpServer接口,是TCP服务器的具体实现。
|
||||||
|
|
||||||
|
* **TcpModuleMakePtr.h/TcpModuleMakePtr.cpp**:提供了创建TCP服务器和客户端实例的工厂方法。
|
||||||
|
|
||||||
|
* **TcpServerHandle.h/TcpServerHandle.cpp**:管理TCP服务器的实例,提供了添加和获取服务器实例的方法。
|
||||||
|
|
||||||
|
* **TcpClientAcceptImpl.h/TcpClientAcceptImpl.cpp**:实现了ITcpClientAccept接口,处理客户端连接的接受和数据交换。
|
||||||
|
|
||||||
|
# 一些易混淆的点
|
||||||
|
1. 客户端创建的套接字包含指定`目标的IP地址和端口号`(TcpClientImpl类中的init函数),服务器创建的套接字只包含`本机IP地址和监听端口`。
|
||||||
|
|
||||||
|
2. 在网络编程中,`服务器`通常会在一个监听端口上等待来自客户端的连接请求。当服务器接受到一个连接请求时,它会创建一个新的套接字(或文件描述符)来表示这个新建立的连接(TcpClientAccept类实例),并且通常会为这个新的连接设置一系列的事件回调函数。
|
||||||
|
|
||||||
|
3. 客户端实例(TcpClientImpl类对象)进行init操作时,会创建一个套接字并对目标服务器发出连接请求并启动事件循环(Loop函数),然后客户端实例会一直进行事件循环(监听是否有读写操作)直至连接关闭(Close函数)。
|
||||||
|
|
||||||
|
4. 服务器`监听连接的套接字`和`连接后新建立的套接字`要分别设置回调函数,这是两个东西,不要混淆。
|
||||||
|
|
||||||
|
|
||||||
|
# 该模块的实现过程
|
||||||
|
## 服务器端:
|
||||||
|
1. 创建服务器端套接字:使用 hloop_create_tcp_server 函数创建一个新的 TCP 服务器端套接字,并指定要监听的 IP 地址和端口号。
|
||||||
|
2. 设置回调函数:为服务器端套接字设置回调函数,包括:
|
||||||
|
on_accept:当有新的客户端尝试连接时调用。
|
||||||
|
on_close:当服务器端套接字关闭时调用。
|
||||||
|
3. 启动事件循环:使用 hloop_run 启动服务器的事件循环,等待客户端的连接请求。
|
||||||
|
4. 接受连接:在 on_accept 回调函数中,接受客户端的连接请求,并创建用于该连接的新套接字。
|
||||||
|
5. 创建客户端接受对象:为新的客户端连接创建一个 TcpClientAcceptImpl 对象,并设置相应的回调函数。
|
||||||
|
on_close:当客户端连接关闭时调用。
|
||||||
|
on_recv:当客户端发送数据时调用。
|
||||||
|
6. 管理客户端连接:将新创建的客户端接受对象添加到管理容器中,以便跟踪和管理。
|
||||||
|
## 客户端:
|
||||||
|
1. 创建客户端套接字:使用 hio_create_socket 函数创建一个新的 TCP 客户端套接字。
|
||||||
|
2. 设置回调函数:为客户端套接字设置回调函数,包括:
|
||||||
|
on_connect:当连接成功建立时调用。
|
||||||
|
on_close:当连接关闭时调用。
|
||||||
|
on_message:当接收到服务器发送的数据时调用。
|
||||||
|
3. 连接到服务器:使用 hio_connect 函数向服务器发起连接请求。
|
||||||
|
4. 启动事件循环:使用 hloop_run 启动客户端的事件循环,等待连接结果和数据传输。
|
||||||
|
5. 处理连接结果:在 on_connect 回调函数中处理连接结果,如果连接成功,可以开始发送和接收数据。
|
|
@ -16,6 +16,7 @@
|
||||||
#define I_TCP_CLIENT_H
|
#define I_TCP_CLIENT_H
|
||||||
#include "StatusCode.h"
|
#include "StatusCode.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <sys/types.h>
|
||||||
class ITcpClient
|
class ITcpClient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -27,6 +28,9 @@ public:
|
||||||
virtual ssize_t Write(const void *buf, const size_t bufLenght);
|
virtual ssize_t Write(const void *buf, const size_t bufLenght);
|
||||||
virtual void Closed(void);
|
virtual void Closed(void);
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* @brief Verify that the header of the client object is legal.
|
||||||
|
*/
|
||||||
typedef struct i_tcp_client_header
|
typedef struct i_tcp_client_header
|
||||||
{
|
{
|
||||||
const char *mCheckName;
|
const char *mCheckName;
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
#include "StatusCode.h"
|
#include "StatusCode.h"
|
||||||
#include "TcpModule.h"
|
#include "TcpModule.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
/**
|
||||||
|
* @brief Handle data interaction and connection state changes on established TCP connections.
|
||||||
|
*/
|
||||||
class ITcpClientAccept
|
class ITcpClientAccept
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -35,6 +38,9 @@ public:
|
||||||
virtual void Init(void);
|
virtual void Init(void);
|
||||||
virtual void UnInit(void);
|
virtual void UnInit(void);
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* @brief Verify that the header of the server object is legal.
|
||||||
|
*/
|
||||||
typedef struct i_tcp_server_header
|
typedef struct i_tcp_server_header
|
||||||
{
|
{
|
||||||
const char *mCheckName;
|
const char *mCheckName;
|
||||||
|
|
|
@ -23,18 +23,34 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
/**
|
||||||
|
* @brief Called when data is received on a TCP connection.
|
||||||
|
*
|
||||||
|
* @param io Client's socket
|
||||||
|
* @param buf The transmitted data content
|
||||||
|
* @param len Byte length of transmitted data
|
||||||
|
*/
|
||||||
static void on_message(hio_t *io, void *buf, int len)
|
static void on_message(hio_t *io, void *buf, int len)
|
||||||
{
|
{
|
||||||
LogInfo("onmessage: %.*s\n", len, (char *)buf);
|
LogInfo("onmessage: %.*s\n", len, (char *)buf);
|
||||||
TcpClientImpl *tcpClient = (TcpClientImpl *)hevent_userdata(io);
|
TcpClientImpl *tcpClient = (TcpClientImpl *)hevent_userdata(io);
|
||||||
tcpClient->Readed(buf, len);
|
tcpClient->Readed(buf, len);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Called when TCP connection is established.
|
||||||
|
* @param io Client's socket
|
||||||
|
*/
|
||||||
static void on_connect(hio_t *io)
|
static void on_connect(hio_t *io)
|
||||||
{
|
{
|
||||||
LogInfo("onconnect: connfd=%d\n", hio_fd(io));
|
LogInfo("onconnect: connfd=%d\n", hio_fd(io));
|
||||||
hio_setcb_read(io, on_message);
|
hio_setcb_read(io, on_message);
|
||||||
|
/// Start a read operation. Read data if it arrives.
|
||||||
hio_read(io);
|
hio_read(io);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Called when tcp connection is disconnected.
|
||||||
|
* @param io Client't socket
|
||||||
|
*/
|
||||||
static void on_close(hio_t *io)
|
static void on_close(hio_t *io)
|
||||||
{
|
{
|
||||||
LogInfo("onclose: connfd=%d error=%d\n", hio_fd(io), hio_error(io));
|
LogInfo("onclose: connfd=%d error=%d\n", hio_fd(io), hio_error(io));
|
||||||
|
@ -44,23 +60,43 @@ static void on_close(hio_t *io)
|
||||||
TcpClientImpl::TcpClientImpl(const TcpClientParam ¶m, const void *object) : mParam(param), mObjectThis(object)
|
TcpClientImpl::TcpClientImpl(const TcpClientParam ¶m, const void *object) : mParam(param), mObjectThis(object)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Create a socket and connect it, and start an event loop to listen to io object operations (read and write,
|
||||||
|
* etc.)
|
||||||
|
*/
|
||||||
void TcpClientImpl::Init(void)
|
void TcpClientImpl::Init(void)
|
||||||
{
|
{
|
||||||
constexpr int NO_FALGS = 0;
|
constexpr int NO_FALGS = 0;
|
||||||
|
/// Initialize event loop
|
||||||
mLoop = hloop_new(NO_FALGS);
|
mLoop = hloop_new(NO_FALGS);
|
||||||
if (nullptr == mLoop) {
|
if (nullptr == mLoop) {
|
||||||
LogError("TcpClientImpl::Init hloop_new failed.\n");
|
LogError("TcpClientImpl::Init hloop_new failed.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief The client's socket, which is used to actively send connection requests to the server and handle related
|
||||||
|
* I/O operations, has no listening function.
|
||||||
|
* @param mLoop Event loop.
|
||||||
|
* When I/O events (connection closed, connection successful, data readable, etc.) occur, the event loop will call
|
||||||
|
* the corresponding callback function to handle them.
|
||||||
|
*
|
||||||
|
* @param mParam.mIp Server IP address
|
||||||
|
* @param mParam.mPort Server port
|
||||||
|
* @param HIO_TYPE_TCP TCP connection
|
||||||
|
* @param HIO_CLIENT_SIDE Indicates that the socket will be used as a client.
|
||||||
|
*
|
||||||
|
*/
|
||||||
hio_t *io = hio_create_socket(mLoop, mParam.mIp, mParam.mPort, HIO_TYPE_TCP, HIO_CLIENT_SIDE);
|
hio_t *io = hio_create_socket(mLoop, mParam.mIp, mParam.mPort, HIO_TYPE_TCP, HIO_CLIENT_SIDE);
|
||||||
if (nullptr == io) {
|
if (nullptr == io) {
|
||||||
LogError("TcpClientImpl::Init hio_create_socket failed.\n");
|
LogError("TcpClientImpl::Init hio_create_socket failed.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hevent_set_userdata(io, this);
|
hevent_set_userdata(io, this);
|
||||||
|
/// Set the callback function of successful connection, and there is no connection operation.
|
||||||
hio_setcb_connect(io, on_connect);
|
hio_setcb_connect(io, on_connect);
|
||||||
|
/// Set the callback function to close the connection, and there is no connection operation.
|
||||||
hio_setcb_close(io, on_close);
|
hio_setcb_close(io, on_close);
|
||||||
hio_connect(io);
|
hio_connect(io); ///< Connection operation
|
||||||
mIo = io;
|
mIo = io;
|
||||||
std::shared_ptr<TcpClientImpl> impl = std::dynamic_pointer_cast<TcpClientImpl>(shared_from_this());
|
std::shared_ptr<TcpClientImpl> impl = std::dynamic_pointer_cast<TcpClientImpl>(shared_from_this());
|
||||||
auto recvThread = [](std::shared_ptr<TcpClientImpl> tcpClient) {
|
auto recvThread = [](std::shared_ptr<TcpClientImpl> tcpClient) {
|
||||||
|
@ -68,6 +104,9 @@ void TcpClientImpl::Init(void)
|
||||||
};
|
};
|
||||||
mTcpClientThread = std::thread(recvThread, impl);
|
mTcpClientThread = std::thread(recvThread, impl);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief De-initialize the TCP client, close the client't socket and wait for the event cycle to end.
|
||||||
|
*/
|
||||||
void TcpClientImpl::UnInit(void)
|
void TcpClientImpl::UnInit(void)
|
||||||
{
|
{
|
||||||
if (nullptr != mIo) {
|
if (nullptr != mIo) {
|
||||||
|
@ -79,6 +118,12 @@ void TcpClientImpl::UnInit(void)
|
||||||
mTcpClientThread.join();
|
mTcpClientThread.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Read the data sent by the server in tcp connection.
|
||||||
|
*
|
||||||
|
* @param data Data content sent by the server
|
||||||
|
* @param length Byte length of data content sent by the server.
|
||||||
|
*/
|
||||||
void TcpClientImpl::Readed(const void *data, size_t length)
|
void TcpClientImpl::Readed(const void *data, size_t length)
|
||||||
{
|
{
|
||||||
if (nullptr != mParam.mReadFunc) {
|
if (nullptr != mParam.mReadFunc) {
|
||||||
|
@ -87,6 +132,13 @@ void TcpClientImpl::Readed(const void *data, size_t length)
|
||||||
}
|
}
|
||||||
LogError("mParam.mReadFunc is nullptr.\n");
|
LogError("mParam.mReadFunc is nullptr.\n");
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief The client writes data to the server, and the writing operation can only be performed in the connected state.
|
||||||
|
*
|
||||||
|
* @param buf Content of written data
|
||||||
|
* @param bufLenght Byte length of written data
|
||||||
|
* @return ssize_t
|
||||||
|
*/
|
||||||
ssize_t TcpClientImpl::Write(const void *buf, const size_t bufLenght)
|
ssize_t TcpClientImpl::Write(const void *buf, const size_t bufLenght)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> locker(mMutex);
|
std::lock_guard<std::mutex> locker(mMutex);
|
||||||
|
@ -94,8 +146,13 @@ ssize_t TcpClientImpl::Write(const void *buf, const size_t bufLenght)
|
||||||
LogError("mIo is nullptr.\n");
|
LogError("mIo is nullptr.\n");
|
||||||
return TCP_MODULE_WRITE_ERROR;
|
return TCP_MODULE_WRITE_ERROR;
|
||||||
}
|
}
|
||||||
|
/// Returns the byte length of a packet.If it fails, an error code is returned.
|
||||||
return hio_write(mIo, buf, bufLenght);
|
return hio_write(mIo, buf, bufLenght);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Close the tcp connection and stop the event loop (reading and writing I/O objects).
|
||||||
|
*
|
||||||
|
*/
|
||||||
void TcpClientImpl::Closed(void)
|
void TcpClientImpl::Closed(void)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> locker(mMutex);
|
std::lock_guard<std::mutex> locker(mMutex);
|
||||||
|
@ -108,6 +165,10 @@ void TcpClientImpl::Closed(void)
|
||||||
hloop_stop(mLoop);
|
hloop_stop(mLoop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Run an event loop and release resources after completion or error.
|
||||||
|
*
|
||||||
|
*/
|
||||||
void TcpClientImpl::Loop(void)
|
void TcpClientImpl::Loop(void)
|
||||||
{
|
{
|
||||||
if (nullptr == mLoop) {
|
if (nullptr == mLoop) {
|
||||||
|
@ -120,15 +181,17 @@ void TcpClientImpl::Loop(void)
|
||||||
}
|
}
|
||||||
std::shared_ptr<ITcpClient> *NewTcpClient(const TcpClientParam ¶m)
|
std::shared_ptr<ITcpClient> *NewTcpClient(const TcpClientParam ¶m)
|
||||||
{
|
{
|
||||||
LogInfo("Create tcp server object.\n");
|
LogInfo("Create tcp client object.\n");
|
||||||
TcpClient *impl = (TcpClient *)malloc(sizeof(TcpClient));
|
TcpClient *impl = (TcpClient *)malloc(sizeof(TcpClient));
|
||||||
if (nullptr == impl) {
|
if (nullptr == impl) {
|
||||||
LogError("NewTcpServer::malloc failed.\n");
|
LogError("NewTcpServer::malloc failed.\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
TcpClient tmp;
|
TcpClient tmp;
|
||||||
|
/// Initialize impl with tmp
|
||||||
memcpy((void *)impl, (void *)&tmp, sizeof(TcpClient));
|
memcpy((void *)impl, (void *)&tmp, sizeof(TcpClient));
|
||||||
impl->mHeader.mCheckName = GetTcpClientModuleName();
|
impl->mHeader.mCheckName = GetTcpClientModuleName();
|
||||||
|
/// ObjectThis is actually a pointer to mTcpClient in the TcpClient structure.
|
||||||
std::shared_ptr<ITcpClient> *objectThis =
|
std::shared_ptr<ITcpClient> *objectThis =
|
||||||
(std::shared_ptr<ITcpClient> *)(((char *)impl) + sizeof(ITcpClientHeader));
|
(std::shared_ptr<ITcpClient> *)(((char *)impl) + sizeof(ITcpClientHeader));
|
||||||
impl->mTcpClient = std::make_shared<TcpClientImpl>(param, objectThis);
|
impl->mTcpClient = std::make_shared<TcpClientImpl>(param, objectThis);
|
||||||
|
|
|
@ -27,20 +27,21 @@ class TcpClientImpl : public ITcpClient, public std::enable_shared_from_this<Tcp
|
||||||
public:
|
public:
|
||||||
TcpClientImpl(const TcpClientParam ¶m, const void *object);
|
TcpClientImpl(const TcpClientParam ¶m, const void *object);
|
||||||
virtual ~TcpClientImpl() = default;
|
virtual ~TcpClientImpl() = default;
|
||||||
void Init(void) override;
|
void Init(void) override; ///< Create a socket and connect it, and start an event loop to listen to io object
|
||||||
void UnInit(void) override;
|
///< operations (read and write, etc.)
|
||||||
void Readed(const void *data, size_t length) override;
|
void UnInit(void) override; ///< close the client't socket and wait for the event cycle to end.
|
||||||
ssize_t Write(const void *buf, const size_t bufLenght) override;
|
void Readed(const void *data, size_t length) override; ///< Read the data sent by the server in tcp connection.
|
||||||
void Closed(void) override;
|
ssize_t Write(const void *buf, const size_t bufLenght) override; ///< client writes data to the server
|
||||||
|
void Closed(void) override; ///< Close the tcp connection and stop the event loop (reading and writing I/O objects).
|
||||||
void Loop(void);
|
void Loop(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex mMutex;
|
std::mutex mMutex; ///< A mutex lock used to synchronize access to shared resources.
|
||||||
hloop_t *mLoop;
|
hloop_t *mLoop; ///< Event loop, Listen for read/write or connection closing operations.
|
||||||
hio_t *mIo;
|
hio_t *mIo; ///< Client's socket
|
||||||
const TcpClientParam mParam;
|
const TcpClientParam mParam; ///< Basic information of the client, including port, ip, reading and closing.
|
||||||
std::thread mTcpClientThread;
|
std::thread mTcpClientThread; ///< A separate thread that runs an event loop to receive and process network data
|
||||||
const void *mObjectThis;
|
const void *mObjectThis; ///< ObjectThis is used to verify whether the client is legal.
|
||||||
};
|
};
|
||||||
std::shared_ptr<ITcpClient> *NewTcpClient(const TcpClientParam ¶m);
|
std::shared_ptr<ITcpClient> *NewTcpClient(const TcpClientParam ¶m);
|
||||||
#endif
|
#endif
|
|
@ -21,6 +21,15 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
/**
|
||||||
|
* @brief Verify that object is a legitimate (existing) server.
|
||||||
|
*
|
||||||
|
* @param object Save the address of the character pointer variable.
|
||||||
|
* Should be substituted into the private member objectThis of the client instance.
|
||||||
|
* If the value of the character pointer pointed by *object is "tcp_server", return turn
|
||||||
|
* @return true Indicates that the server exists.
|
||||||
|
* @return false Indicates that the server does not exist
|
||||||
|
*/
|
||||||
static bool TcpServerObjectCheck(void *object)
|
static bool TcpServerObjectCheck(void *object)
|
||||||
{
|
{
|
||||||
if (nullptr == object) {
|
if (nullptr == object) {
|
||||||
|
@ -33,6 +42,14 @@ static bool TcpServerObjectCheck(void *object)
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Verify that object is a legitimate (existing) client.
|
||||||
|
*
|
||||||
|
* @param object Save the address of the character pointer variable.
|
||||||
|
*
|
||||||
|
* @return true Indicates that the client exists.
|
||||||
|
* @return false Indicates that the client does not exist
|
||||||
|
*/
|
||||||
static bool TcpClientObjectCheck(void *object)
|
static bool TcpClientObjectCheck(void *object)
|
||||||
{
|
{
|
||||||
if (nullptr == object) {
|
if (nullptr == object) {
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
#include "StatusCode.h"
|
#include "StatusCode.h"
|
||||||
#include "TcpModule.h"
|
#include "TcpModule.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
/**
|
||||||
|
* @brief A factory class that indirectly creates server-side and client-side instances through this class
|
||||||
|
*
|
||||||
|
*/
|
||||||
class TcpModuleMakePtr
|
class TcpModuleMakePtr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -16,6 +16,12 @@
|
||||||
#include "ILog.h"
|
#include "ILog.h"
|
||||||
#include "ITcpServer.h"
|
#include "ITcpServer.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the singleton instance of TcpServerHandle
|
||||||
|
* @param impl Optional implementation pointer to replace the current instance
|
||||||
|
* @return The singleton instance of TcpServerHandle
|
||||||
|
*/
|
||||||
std::shared_ptr<TcpServerHandle> &TcpServerHandle::GetInstance(std::shared_ptr<TcpServerHandle> *impl)
|
std::shared_ptr<TcpServerHandle> &TcpServerHandle::GetInstance(std::shared_ptr<TcpServerHandle> *impl)
|
||||||
{
|
{
|
||||||
static auto instance = std::make_shared<TcpServerHandle>();
|
static auto instance = std::make_shared<TcpServerHandle>();
|
||||||
|
@ -30,11 +36,24 @@ std::shared_ptr<TcpServerHandle> &TcpServerHandle::GetInstance(std::shared_ptr<T
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a server
|
||||||
|
* @param fd File descriptor of the server
|
||||||
|
* @param server Shared pointer to the ITcpServer instance
|
||||||
|
*/
|
||||||
void TcpServerHandle::AddServer(const int &fd, const std::shared_ptr<ITcpServer> &server)
|
void TcpServerHandle::AddServer(const int &fd, const std::shared_ptr<ITcpServer> &server)
|
||||||
{
|
{
|
||||||
LogInfo("AddServer fd = %d\n", fd);
|
LogInfo("AddServer fd = %d\n", fd);
|
||||||
mFd[fd] = server;
|
mFd[fd] = server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a server by file descriptor
|
||||||
|
* @param fd File descriptor of the server
|
||||||
|
* @param server Reference to a shared pointer to store the ITcpServer instance
|
||||||
|
* @return True if the server is found, false otherwise
|
||||||
|
*/
|
||||||
bool TcpServerHandle::GetServer(const int &fd, std::shared_ptr<ITcpServer> &server)
|
bool TcpServerHandle::GetServer(const int &fd, std::shared_ptr<ITcpServer> &server)
|
||||||
{
|
{
|
||||||
auto it = mFd.find(fd);
|
auto it = mFd.find(fd);
|
||||||
|
|
|
@ -20,13 +20,36 @@
|
||||||
class TcpServerHandle
|
class TcpServerHandle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Default constructor
|
||||||
|
*/
|
||||||
TcpServerHandle() = default;
|
TcpServerHandle() = default;
|
||||||
|
/**
|
||||||
|
* @brief Default destructor
|
||||||
|
*/
|
||||||
~TcpServerHandle() = default;
|
~TcpServerHandle() = default;
|
||||||
|
/**
|
||||||
|
* @brief Get the singleton instance of TcpServerHandle
|
||||||
|
* @param impl Optional implementation pointer to replace the current instance
|
||||||
|
* @return The singleton instance of TcpServerHandle
|
||||||
|
*/
|
||||||
static std::shared_ptr<TcpServerHandle> &GetInstance(std::shared_ptr<TcpServerHandle> *impl = nullptr);
|
static std::shared_ptr<TcpServerHandle> &GetInstance(std::shared_ptr<TcpServerHandle> *impl = nullptr);
|
||||||
|
/**
|
||||||
|
* @brief Add a server
|
||||||
|
* @param fd File descriptor of the server
|
||||||
|
* @param server Shared pointer to the ITcpServer instance
|
||||||
|
*/
|
||||||
void AddServer(const int &fd, const std::shared_ptr<ITcpServer> &server);
|
void AddServer(const int &fd, const std::shared_ptr<ITcpServer> &server);
|
||||||
|
/**
|
||||||
|
* @brief Get a server by file descriptor
|
||||||
|
* @param fd File descriptor of the server
|
||||||
|
* @param server Reference to a shared pointer to store the ITcpServer instance
|
||||||
|
* @return True if the server is found, false otherwise
|
||||||
|
*/
|
||||||
bool GetServer(const int &fd, std::shared_ptr<ITcpServer> &server);
|
bool GetServer(const int &fd, std::shared_ptr<ITcpServer> &server);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// Store multiple servers
|
||||||
std::map<int, std::shared_ptr<ITcpServer>> mFd;
|
std::map<int, std::shared_ptr<ITcpServer>> mFd;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
|
@ -24,18 +24,35 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
/**
|
||||||
|
* @brief Handle the close connection event.
|
||||||
|
*
|
||||||
|
* @param io Server's socket
|
||||||
|
*/
|
||||||
static void on_close(hio_t *io)
|
static void on_close(hio_t *io)
|
||||||
{
|
{
|
||||||
LogInfo("on_close fd=%d error=%d\n", hio_fd(io), hio_error(io));
|
LogInfo("on_close fd=%d error=%d\n", hio_fd(io), hio_error(io));
|
||||||
TcpServerImpl *server = (TcpServerImpl *)hevent_userdata(io);
|
TcpServerImpl *server = (TcpServerImpl *)hevent_userdata(io);
|
||||||
server->RemoveClient(io);
|
server->RemoveClient(io);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Close the port on which the server listens for client connections.
|
||||||
|
*
|
||||||
|
* @param io The port on which the server listens for client connections.
|
||||||
|
*/
|
||||||
static void server_on_close(hio_t *io)
|
static void server_on_close(hio_t *io)
|
||||||
{
|
{
|
||||||
LogInfo("server_on_close fd=%d error=%d\n", hio_fd(io), hio_error(io));
|
LogInfo("server_on_close fd=%d error=%d\n", hio_fd(io), hio_error(io));
|
||||||
TcpServerImpl *server = (TcpServerImpl *)hevent_userdata(io);
|
TcpServerImpl *server = (TcpServerImpl *)hevent_userdata(io);
|
||||||
server->Closed();
|
server->Closed();
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief The server processes data
|
||||||
|
*
|
||||||
|
* @param io Socket
|
||||||
|
* @param buf data
|
||||||
|
* @param readbytes bytes
|
||||||
|
*/
|
||||||
static void on_recv(hio_t *io, void *buf, int readbytes)
|
static void on_recv(hio_t *io, void *buf, int readbytes)
|
||||||
{
|
{
|
||||||
LogInfo("on_recv fd=%d readbytes=%d\n", hio_fd(io), readbytes);
|
LogInfo("on_recv fd=%d readbytes=%d\n", hio_fd(io), readbytes);
|
||||||
|
@ -48,6 +65,11 @@ static void on_recv(hio_t *io, void *buf, int readbytes)
|
||||||
std::shared_ptr<ITcpClientAccept> *client = server->GetClient(io);
|
std::shared_ptr<ITcpClientAccept> *client = server->GetClient(io);
|
||||||
(*client)->Readed((const char *)buf, readbytes);
|
(*client)->Readed((const char *)buf, readbytes);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Handles a new accept client connection event
|
||||||
|
*
|
||||||
|
* @param io Socket for newly accepted client connection
|
||||||
|
*/
|
||||||
static void on_accept(hio_t *io)
|
static void on_accept(hio_t *io)
|
||||||
{
|
{
|
||||||
LogInfo("on_accept connfd=%d\n", hio_fd(io));
|
LogInfo("on_accept connfd=%d\n", hio_fd(io));
|
||||||
|
@ -63,12 +85,17 @@ static void on_accept(hio_t *io)
|
||||||
// std::shared_ptr<ITcpClientAccept> *client = NewTcpClientAccept(io);
|
// std::shared_ptr<ITcpClientAccept> *client = NewTcpClientAccept(io);
|
||||||
TcpServerImpl *server = (TcpServerImpl *)hevent_userdata(io);
|
TcpServerImpl *server = (TcpServerImpl *)hevent_userdata(io);
|
||||||
server->AddClient(io);
|
server->AddClient(io);
|
||||||
|
/// Set up a read event
|
||||||
hio_read_start(io);
|
hio_read_start(io);
|
||||||
}
|
}
|
||||||
TcpClientAcceptImpl::TcpClientAcceptImpl(const hio_t *io, const void *object, const ClientAcceptParam ¶m)
|
TcpClientAcceptImpl::TcpClientAcceptImpl(const hio_t *io, const void *object, const ClientAcceptParam ¶m)
|
||||||
: mIo(io), mObjectThis(object), mParam(param)
|
: mIo(io), mObjectThis(object), mParam(param)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Disconnect the client
|
||||||
|
*
|
||||||
|
*/
|
||||||
void TcpClientAcceptImpl::Close(void)
|
void TcpClientAcceptImpl::Close(void)
|
||||||
{
|
{
|
||||||
if (nullptr != mIo) {
|
if (nullptr != mIo) {
|
||||||
|
@ -76,14 +103,28 @@ void TcpClientAcceptImpl::Close(void)
|
||||||
hio_close(io);
|
hio_close(io);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief The server reads the data received by tcp connection.
|
||||||
|
*
|
||||||
|
* @param data Read data content
|
||||||
|
* @param length Read data byte length
|
||||||
|
*/
|
||||||
void TcpClientAcceptImpl::Readed(const void *data, size_t length)
|
void TcpClientAcceptImpl::Readed(const void *data, size_t length)
|
||||||
{
|
{
|
||||||
if (nullptr != mParam.mReadFunc) {
|
if (nullptr != mParam.mReadFunc) {
|
||||||
mParam.mReadFunc(data, length, mObjectThis);
|
mParam.mReadFunc(data, length, mObjectThis);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogWarning("mParam.mClosedFunc is null\n");
|
LogWarning("mParam.mReadedFunc is null\n");
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief The server writes data to the tcp connection.
|
||||||
|
*
|
||||||
|
* @param data Written data
|
||||||
|
* @param length Byte length of written data
|
||||||
|
* @return ssize_t
|
||||||
|
* Returns the number of bytes written if the writing is successful, and returns the error code -1 if it fails.
|
||||||
|
*/
|
||||||
ssize_t TcpClientAcceptImpl::Write(const void *data, size_t length)
|
ssize_t TcpClientAcceptImpl::Write(const void *data, size_t length)
|
||||||
{
|
{
|
||||||
if (mIo) {
|
if (mIo) {
|
||||||
|
@ -93,6 +134,11 @@ ssize_t TcpClientAcceptImpl::Write(const void *data, size_t length)
|
||||||
LogError("mIo is null\n");
|
LogError("mIo is null\n");
|
||||||
return TCP_MODULE_WRITE_ERROR;
|
return TCP_MODULE_WRITE_ERROR;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Used to perform some cleaning work or notify upper layer logic when a TCP client accepts a connection that is
|
||||||
|
* closed
|
||||||
|
*
|
||||||
|
*/
|
||||||
void TcpClientAcceptImpl::Closed(void)
|
void TcpClientAcceptImpl::Closed(void)
|
||||||
{
|
{
|
||||||
if (nullptr != mParam.mClosedFunc) {
|
if (nullptr != mParam.mClosedFunc) {
|
||||||
|
@ -106,14 +152,21 @@ TcpServerImpl::TcpServerImpl(const TcpServerParam param) : mParam(param)
|
||||||
mLoop = nullptr;
|
mLoop = nullptr;
|
||||||
mIo = nullptr;
|
mIo = nullptr;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Create an event loop to listen for connection requests from the server socket, set up relevant callback
|
||||||
|
* functions, and start a separate thread to run the event loop
|
||||||
|
*
|
||||||
|
*/
|
||||||
void TcpServerImpl::Init(void)
|
void TcpServerImpl::Init(void)
|
||||||
{
|
{
|
||||||
constexpr int NO_FALGS = 0;
|
constexpr int NO_FALGS = 0;
|
||||||
|
/// mLoop is used to manage all I/O objects and the events that occur on them.
|
||||||
mLoop = hloop_new(NO_FALGS);
|
mLoop = hloop_new(NO_FALGS);
|
||||||
if (nullptr == mLoop) {
|
if (nullptr == mLoop) {
|
||||||
LogError("hloop_new failed\n");
|
LogError("hloop_new failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/// Create a socket to listen whether a new client sends a connection request.
|
||||||
hio_t *listenio = hloop_create_tcp_server(mLoop, mParam.mIp, mParam.mPort, on_accept);
|
hio_t *listenio = hloop_create_tcp_server(mLoop, mParam.mIp, mParam.mPort, on_accept);
|
||||||
if (nullptr == listenio) {
|
if (nullptr == listenio) {
|
||||||
LogError("hloop_create_tcp_server failed\n");
|
LogError("hloop_create_tcp_server failed\n");
|
||||||
|
@ -132,11 +185,17 @@ void TcpServerImpl::Init(void)
|
||||||
};
|
};
|
||||||
mTcpServerThread = std::thread(recvThread, impl);
|
mTcpServerThread = std::thread(recvThread, impl);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief De-initialize the TCP server, close the I/O object and wait for the receiving thread to end.
|
||||||
|
*
|
||||||
|
*/
|
||||||
void TcpServerImpl::UnInit(void)
|
void TcpServerImpl::UnInit(void)
|
||||||
{
|
{
|
||||||
LogInfo("UnInit TcpServerImpl\n");
|
LogInfo("UnInit TcpServerImpl\n");
|
||||||
|
/// Close all client connections
|
||||||
FreeClients();
|
FreeClients();
|
||||||
if (nullptr != mIo) {
|
if (nullptr != mIo) {
|
||||||
|
/// Turn off connection monitoring
|
||||||
hio_close(mIo);
|
hio_close(mIo);
|
||||||
mIo = nullptr;
|
mIo = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -144,6 +203,10 @@ void TcpServerImpl::UnInit(void)
|
||||||
mTcpServerThread.join();
|
mTcpServerThread.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Run an event loop and release resources after completion or error.
|
||||||
|
*
|
||||||
|
*/
|
||||||
void TcpServerImpl::Loop(void)
|
void TcpServerImpl::Loop(void)
|
||||||
{
|
{
|
||||||
if (nullptr == mLoop) {
|
if (nullptr == mLoop) {
|
||||||
|
@ -154,6 +217,11 @@ void TcpServerImpl::Loop(void)
|
||||||
hloop_free(&mLoop);
|
hloop_free(&mLoop);
|
||||||
mLoop = nullptr;
|
mLoop = nullptr;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Add a newly connected client to the server connection management list.
|
||||||
|
*
|
||||||
|
* @param io Socket associated with server and client connections
|
||||||
|
*/
|
||||||
void TcpServerImpl::AddClient(hio_t *io)
|
void TcpServerImpl::AddClient(hio_t *io)
|
||||||
{
|
{
|
||||||
mMutex.lock();
|
mMutex.lock();
|
||||||
|
@ -165,6 +233,7 @@ void TcpServerImpl::AddClient(hio_t *io)
|
||||||
SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
|
SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
|
||||||
std::shared_ptr<ITcpClientAccept> *addClient = NewTcpClientAccept(io, mParam.mClientAcceptParam);
|
std::shared_ptr<ITcpClientAccept> *addClient = NewTcpClientAccept(io, mParam.mClientAcceptParam);
|
||||||
mClients[hio_fd(io)] = addClient;
|
mClients[hio_fd(io)] = addClient;
|
||||||
|
/// Check whether the server side accepts the connection of the client side.
|
||||||
if (mParam.mAcceptClientFunc) {
|
if (mParam.mAcceptClientFunc) {
|
||||||
if (mParam.mAcceptClientFunc(addClient, peeraddrstr) == true) {
|
if (mParam.mAcceptClientFunc(addClient, peeraddrstr) == true) {
|
||||||
mMutex.unlock();
|
mMutex.unlock();
|
||||||
|
@ -176,6 +245,12 @@ void TcpServerImpl::AddClient(hio_t *io)
|
||||||
hio_close(io);
|
hio_close(io);
|
||||||
LogWarning("AddClient failed.\n");
|
LogWarning("AddClient failed.\n");
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Retrieve the corresponding client acceptance object based on the socket handle.
|
||||||
|
*
|
||||||
|
* @param io Handle pointing to socket
|
||||||
|
* @return std::shared_ptr<ITcpClientAccept>*
|
||||||
|
*/
|
||||||
std::shared_ptr<ITcpClientAccept> *TcpServerImpl::GetClient(hio_t *io)
|
std::shared_ptr<ITcpClientAccept> *TcpServerImpl::GetClient(hio_t *io)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> locker(mMutex);
|
std::lock_guard<std::mutex> locker(mMutex);
|
||||||
|
@ -186,6 +261,11 @@ std::shared_ptr<ITcpClientAccept> *TcpServerImpl::GetClient(hio_t *io)
|
||||||
LogError("GetClient failed, client not exit.\n");
|
LogError("GetClient failed, client not exit.\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Removes a specific connection from the list of client connections maintained by the server.
|
||||||
|
*
|
||||||
|
* @param io A server-side socket associated with an established client connection.
|
||||||
|
*/
|
||||||
void TcpServerImpl::RemoveClient(hio_t *io)
|
void TcpServerImpl::RemoveClient(hio_t *io)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> locker(mMutex);
|
std::lock_guard<std::mutex> locker(mMutex);
|
||||||
|
@ -203,6 +283,10 @@ void TcpServerImpl::RemoveClient(hio_t *io)
|
||||||
LogError("RemoveClient failed, client not exit.\n");
|
LogError("RemoveClient failed, client not exit.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Clear all connected clients.
|
||||||
|
*
|
||||||
|
*/
|
||||||
void TcpServerImpl::FreeClients(void)
|
void TcpServerImpl::FreeClients(void)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> locker(mMutex);
|
std::lock_guard<std::mutex> locker(mMutex);
|
||||||
|
@ -218,6 +302,10 @@ void TcpServerImpl::FreeClients(void)
|
||||||
}
|
}
|
||||||
mClients.clear();
|
mClients.clear();
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Stop listening to the event loop
|
||||||
|
*
|
||||||
|
*/
|
||||||
void TcpServerImpl::Closed(void)
|
void TcpServerImpl::Closed(void)
|
||||||
{
|
{
|
||||||
if (nullptr != mLoop) {
|
if (nullptr != mLoop) {
|
||||||
|
@ -234,6 +322,7 @@ std::shared_ptr<ITcpServer> *NewTcpServer(const TcpServerParam ¶m)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
TcpServer tmp;
|
TcpServer tmp;
|
||||||
|
/// Initialize impl with tmp
|
||||||
memcpy((void *)impl, (void *)&tmp, sizeof(TcpServer));
|
memcpy((void *)impl, (void *)&tmp, sizeof(TcpServer));
|
||||||
impl->mHeader.mCheckName = GetTcpServerModuleName();
|
impl->mHeader.mCheckName = GetTcpServerModuleName();
|
||||||
impl->mTcpServer = std::make_shared<TcpServerImpl>(param);
|
impl->mTcpServer = std::make_shared<TcpServerImpl>(param);
|
||||||
|
@ -241,7 +330,7 @@ std::shared_ptr<ITcpServer> *NewTcpServer(const TcpServerParam ¶m)
|
||||||
}
|
}
|
||||||
std::shared_ptr<ITcpClientAccept> *NewTcpClientAccept(const hio_t *io, const ClientAcceptParam ¶m)
|
std::shared_ptr<ITcpClientAccept> *NewTcpClientAccept(const hio_t *io, const ClientAcceptParam ¶m)
|
||||||
{
|
{
|
||||||
LogInfo("Create tcp server object.\n");
|
LogInfo("Create tcp client accept object.\n");
|
||||||
TcpClientAccept *impl = (TcpClientAccept *)malloc(sizeof(TcpClientAccept));
|
TcpClientAccept *impl = (TcpClientAccept *)malloc(sizeof(TcpClientAccept));
|
||||||
if (nullptr == impl) {
|
if (nullptr == impl) {
|
||||||
LogError("NewTcpServer::malloc failed.\n");
|
LogError("NewTcpServer::malloc failed.\n");
|
||||||
|
@ -250,6 +339,7 @@ std::shared_ptr<ITcpClientAccept> *NewTcpClientAccept(const hio_t *io, const Cli
|
||||||
TcpClientAccept tmp;
|
TcpClientAccept tmp;
|
||||||
memcpy((void *)impl, (void *)&tmp, sizeof(TcpClientAccept));
|
memcpy((void *)impl, (void *)&tmp, sizeof(TcpClientAccept));
|
||||||
impl->mHeader.mCheckName = GetTcpClientAcceptName();
|
impl->mHeader.mCheckName = GetTcpClientAcceptName();
|
||||||
|
/// ObjectThis actually refers to mTcpClientAccept
|
||||||
std::shared_ptr<ITcpClientAccept> *objectThis =
|
std::shared_ptr<ITcpClientAccept> *objectThis =
|
||||||
(std::shared_ptr<ITcpClientAccept> *)(((char *)impl) + sizeof(ITcpServerHeader));
|
(std::shared_ptr<ITcpClientAccept> *)(((char *)impl) + sizeof(ITcpServerHeader));
|
||||||
impl->mTcpClientAccept = std::make_shared<TcpClientAcceptImpl>(io, objectThis, param);
|
impl->mTcpClientAccept = std::make_shared<TcpClientAcceptImpl>(io, objectThis, param);
|
||||||
|
|
|
@ -22,21 +22,32 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
/**
|
||||||
|
* @brief The TcpClient Accept class instance is used to associate with the socket after connecting to the server and
|
||||||
|
* client, responsible for a series of operations (read/write, etc.) after the connection
|
||||||
|
*
|
||||||
|
*/
|
||||||
class TcpClientAcceptImpl : public ITcpClientAccept, public std::enable_shared_from_this<TcpClientAcceptImpl>
|
class TcpClientAcceptImpl : public ITcpClientAccept, public std::enable_shared_from_this<TcpClientAcceptImpl>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TcpClientAcceptImpl(const hio_t *io, const void *object, const ClientAcceptParam ¶m);
|
TcpClientAcceptImpl(const hio_t *io, const void *object, const ClientAcceptParam ¶m);
|
||||||
virtual ~TcpClientAcceptImpl() = default;
|
virtual ~TcpClientAcceptImpl() = default;
|
||||||
void Close(void) override;
|
void Close(void) override; ///< Disconnect the client
|
||||||
void Readed(const void *data, size_t length) override;
|
void Readed(const void *data, size_t length) override; ///< The server reads the data received by tcp connection.
|
||||||
ssize_t Write(const void *data, size_t length) override;
|
ssize_t Write(const void *data, size_t length) override; ///< The server writes data to the tcp connection.
|
||||||
void Closed(void) override;
|
void Closed(void) override; ///< Used to perform some cleaning work or notify upper layer logic when a TCP client
|
||||||
|
///< accepts a connection that is closed
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const hio_t *mIo;
|
const hio_t *mIo; ///< Connected client socket
|
||||||
const void *mObjectThis;
|
const void *mObjectThis; ///< Used to verify whether this type of instance is legal
|
||||||
const ClientAcceptParam mParam;
|
const ClientAcceptParam mParam;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* @brief The TcpServerImpl class is responsible for listening to connection requests from clients and creating an
|
||||||
|
* instance of TcpClientAcceptImpl for each accepted connection.
|
||||||
|
*
|
||||||
|
*/
|
||||||
class TcpServerImpl : public ITcpServer, public std::enable_shared_from_this<TcpServerImpl>
|
class TcpServerImpl : public ITcpServer, public std::enable_shared_from_this<TcpServerImpl>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -44,20 +55,21 @@ public:
|
||||||
virtual ~TcpServerImpl() = default;
|
virtual ~TcpServerImpl() = default;
|
||||||
void Init(void) override;
|
void Init(void) override;
|
||||||
void UnInit(void) override;
|
void UnInit(void) override;
|
||||||
void Loop(void);
|
void Loop(void); ///< Run an event loop and release resources after completion or error.
|
||||||
void AddClient(hio_t *io);
|
void AddClient(hio_t *io); ///< Add a newly connected client to the server connection management list.
|
||||||
std::shared_ptr<ITcpClientAccept> *GetClient(hio_t *io);
|
std::shared_ptr<ITcpClientAccept> *
|
||||||
void RemoveClient(hio_t *io);
|
GetClient(hio_t *io); ///< Retrieve the corresponding client acceptance object based on the socket handle.
|
||||||
void FreeClients(void);
|
void RemoveClient(hio_t *io); ///< Remove the data element in the map, that is, the connected client.
|
||||||
void Closed(void);
|
void FreeClients(void); ///< Clear all connected clients.
|
||||||
|
void Closed(void); ///< Stop listening to the event loop(mLoop)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex mMutex;
|
std::mutex mMutex; ///< A mutex lock used to synchronize access to shared resources.
|
||||||
hloop_t *mLoop;
|
hloop_t *mLoop; ///< Event loop, listening for all io objects
|
||||||
hio_t *mIo;
|
hio_t *mIo; ///< A server socket to listen whether a new client sends a connection request.
|
||||||
const TcpServerParam mParam;
|
const TcpServerParam mParam;
|
||||||
std::thread mTcpServerThread;
|
std::thread mTcpServerThread; ///< A separate thread used to run event loops
|
||||||
std::map<int, std::shared_ptr<ITcpClientAccept> *> mClients;
|
std::map<int, std::shared_ptr<ITcpClientAccept> *> mClients; ///< Container for storing clients connected to servers
|
||||||
};
|
};
|
||||||
std::shared_ptr<ITcpServer> *NewTcpServer(const TcpServerParam ¶m);
|
std::shared_ptr<ITcpServer> *NewTcpServer(const TcpServerParam ¶m);
|
||||||
std::shared_ptr<ITcpClientAccept> *NewTcpClientAccept(const hio_t *io, const ClientAcceptParam ¶m);
|
std::shared_ptr<ITcpClientAccept> *NewTcpClientAccept(const hio_t *io, const ClientAcceptParam ¶m);
|
||||||
|
|
14
utils/UartDevice/readme.md
Normal file
14
utils/UartDevice/readme.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# UartDevice模块
|
||||||
|
该模块是UART设备接口模块,提供了UART 设备操作接口,通过uart通信操作相关的硬件设备。
|
||||||
|
|
||||||
|
# 涉及的知识
|
||||||
|
* uart通信协议
|
||||||
|
* 多线程
|
||||||
|
* C++类和对象
|
||||||
|
* 函数指针
|
||||||
|
|
||||||
|
|
||||||
|
# 各文件的作用
|
||||||
|
* **UartDevice.h**:为上层应用提供了封装好的函数接口,用于与uart硬件设备进行交互。
|
||||||
|
* **UartDevice.cpp**:UartDevice.h中函数接口的具体定义和封装。
|
||||||
|
* **UartDeviceImpl.cpp/UartDeviceImpl.h**:这里面定义和声明的函数是对uart硬件设备更底层更具体的一些操作,它们会被提供给UartDevice.cpp做进一步的封装。
|
Loading…
Reference in New Issue
Block a user