-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathConfigLoader.h
120 lines (108 loc) · 2.48 KB
/
ConfigLoader.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#ifndef _CONFIGLOADER_H_
#define _CONFIGLOADER_H_
// by git@github.com:yuwf/jsonbind.git
#include<memory>
#include<iosfwd>
#include <mutex>
#include <exception>
#include "jsonbind.hpp"
//#include "LLog.h"
//#define ConfigLogError LLOG_FATAL
//#define ConfigLogInfo LLOG_INFO
#define ConfigLogError
#define ConfigLogInfo
// 多线程安全
// 要求 T 定义 Normalize 函数
template <class T>
class ConfigLoader
{
public:
// 获取配置对象,数据对象是只读的,可以被多线程共享
// 获取的对象一定不为空,外层无需判断
std::shared_ptr<const T> GetConfig()
{
std::unique_lock<std::mutex> lock(m_mutex);
if (m_data == nullptr)
{
T* data = new T();
data->Normalize();
m_data = std::shared_ptr<const T>(data);
}
return m_data;
}
// 获取原始配置
std::string GetSrc()
{
std::unique_lock<std::mutex> lock(m_mutex);
return m_src;
}
// 依赖json_bind
bool LoadFromJsonString(const std::string& src)
{
T* data = new T();
std::string err;
if (!data->from_string(src, &err))
{
delete data;
ConfigLogError("LoadJsonFromString err=%s src=%s", err.c_str(), src.c_str());
return false;
}
ConfigLogInfo("LoadJsonFromString Success src=%s", src.c_str());
data->Normalize();
{
std::unique_lock<std::mutex> lock(m_mutex);
m_data = std::shared_ptr<const T>(data);
m_src = src;
}
return true;
}
bool LoadJsonFromFile(const std::string& filename)
{
std::ifstream ifs(filename.c_str(), std::ifstream::in);
if (!ifs.is_open())
{
ConfigLogError("LoadJsonFromFile open fail filename=%s", filename.c_str());
return false;
}
std::stringstream ss;
try
{
ss << ifs.rdbuf();
}
catch (const std::exception& ex)
{
ConfigLogError("LoadJsonFromFile read fail filename=%s ex=%s", filename.c_str(), ex.what());
ifs.close();
return false;
}
ifs.close();
return LoadFromJsonString(ss.str());
}
bool SaveToFile(const std::string& filename)
{
std::ofstream ofs(filename, std::ofstream::out);
if (!ofs.is_open())
{
ConfigLogError("SaveToFile open fail filename=%s", filename.c_str());
return false;
}
std::string src = GetSrc();
try
{
ofs << src; // 文本输出
}
catch (const std::exception& ex)
{
ConfigLogError("SaveToFile write fail filename=%s ex=%s", filename.c_str(), ex.what());
ofs.close();
return false;
}
ofs.close();
return true;
}
private:
std::mutex m_mutex;
std::shared_ptr<const T> m_data;
std::string m_src; // 原始配置
};
#endif