Line data Source code
1 : /**
2 : * @file config.cpp
3 : * @brief Config 类实现
4 : */
5 :
6 : #include "base/config.hpp"
7 : #include <fstream>
8 : #include <algorithm>
9 : #include <iostream>
10 :
11 : namespace fix40 {
12 :
13 592 : Config& Config::instance() {
14 592 : static Config inst;
15 592 : return inst;
16 : }
17 :
18 89 : std::string Config::trim(const std::string& str) {
19 89 : const char* whitespace = " \t\n\r\f\v";
20 89 : size_t first = str.find_first_not_of(whitespace);
21 89 : if (std::string::npos == first) {
22 2 : return "";
23 : }
24 88 : size_t last = str.find_last_not_of(whitespace);
25 88 : return str.substr(first, (last - first + 1));
26 : }
27 :
28 10 : bool Config::load(const std::string& filename) {
29 10 : std::lock_guard<std::mutex> lock(mutex_);
30 10 : data_.clear();
31 :
32 10 : std::ifstream file(filename);
33 10 : if (!file.is_open()) {
34 1 : std::cerr << "Error: Could not open config file " << filename << std::endl;
35 1 : return false;
36 : }
37 :
38 9 : std::string line;
39 9 : std::string current_section;
40 44 : while (std::getline(file, line)) {
41 35 : line = trim(line);
42 35 : if (line.empty() || line[0] == '#' || line[0] == ';') {
43 3 : continue;
44 : }
45 :
46 32 : if (line[0] == '[' && line.back() == ']') {
47 10 : current_section = trim(line.substr(1, line.length() - 2));
48 : } else {
49 22 : size_t delimiter_pos = line.find('=');
50 22 : if (delimiter_pos != std::string::npos) {
51 22 : std::string key = trim(line.substr(0, delimiter_pos));
52 22 : std::string value = trim(line.substr(delimiter_pos + 1));
53 22 : if (!key.empty()) {
54 22 : data_[current_section][key] = value;
55 : }
56 22 : }
57 : }
58 : }
59 9 : return true;
60 10 : }
61 :
62 582 : std::string Config::get(const std::string& section, const std::string& key, const std::string& default_value) {
63 582 : std::lock_guard<std::mutex> lock(mutex_);
64 582 : auto sec_it = data_.find(section);
65 582 : if (sec_it != data_.end()) {
66 19 : auto key_it = sec_it->second.find(key);
67 19 : if (key_it != sec_it->second.end()) {
68 17 : return key_it->second;
69 : }
70 : }
71 565 : return default_value;
72 582 : }
73 :
74 565 : int Config::get_int(const std::string& section, const std::string& key, int default_value) {
75 565 : std::string val_str = get(section, key, "");
76 565 : if (val_str.empty()) {
77 561 : return default_value;
78 : }
79 : try {
80 4 : return std::stoi(val_str);
81 1 : } catch (const std::exception& e) {
82 1 : return default_value;
83 1 : }
84 565 : }
85 :
86 4 : double Config::get_double(const std::string& section, const std::string& key, double default_value) {
87 4 : std::string val_str = get(section, key, "");
88 4 : if (val_str.empty()) {
89 0 : return default_value;
90 : }
91 : try {
92 4 : return std::stod(val_str);
93 1 : } catch (const std::exception& e) {
94 1 : return default_value;
95 1 : }
96 4 : }
97 :
98 : } // namespace fix40
|