1 //
2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #include "td/telegram/ConfigShared.h"
8
9 #include "td/telegram/td_api.h"
10
11 #include "td/utils/logging.h"
12 #include "td/utils/misc.h"
13 #include "td/utils/SliceBuilder.h"
14
15 namespace td {
16
ConfigShared(std::shared_ptr<KeyValueSyncInterface> config_pmc)17 ConfigShared::ConfigShared(std::shared_ptr<KeyValueSyncInterface> config_pmc) : config_pmc_(std::move(config_pmc)) {
18 }
19
set_callback(unique_ptr<Callback> callback)20 void ConfigShared::set_callback(unique_ptr<Callback> callback) {
21 callback_ = std::move(callback);
22 if (callback_ == nullptr) {
23 return;
24 }
25
26 for (const auto &key_value : config_pmc_->get_all()) {
27 on_option_updated(key_value.first);
28 }
29 }
30
set_option_boolean(Slice name,bool value)31 void ConfigShared::set_option_boolean(Slice name, bool value) {
32 if (set_option(name, value ? Slice("Btrue") : Slice("Bfalse"))) {
33 on_option_updated(name);
34 }
35 }
36
set_option_empty(Slice name)37 void ConfigShared::set_option_empty(Slice name) {
38 if (set_option(name, Slice())) {
39 on_option_updated(name);
40 }
41 }
42
set_option_integer(Slice name,int64 value)43 void ConfigShared::set_option_integer(Slice name, int64 value) {
44 if (set_option(name, PSLICE() << "I" << value)) {
45 on_option_updated(name);
46 }
47 }
48
set_option_string(Slice name,Slice value)49 void ConfigShared::set_option_string(Slice name, Slice value) {
50 if (set_option(name, PSLICE() << "S" << value)) {
51 on_option_updated(name);
52 }
53 }
54
have_option(Slice name) const55 bool ConfigShared::have_option(Slice name) const {
56 return config_pmc_->isset(name.str());
57 }
58
get_option(Slice name) const59 string ConfigShared::get_option(Slice name) const {
60 return config_pmc_->get(name.str());
61 }
62
get_options() const63 std::unordered_map<string, string> ConfigShared::get_options() const {
64 return config_pmc_->get_all();
65 }
66
get_option_boolean(Slice name,bool default_value) const67 bool ConfigShared::get_option_boolean(Slice name, bool default_value) const {
68 auto value = get_option(name);
69 if (value.empty()) {
70 return default_value;
71 }
72 if (value == "Btrue") {
73 return true;
74 }
75 if (value == "Bfalse") {
76 return false;
77 }
78 LOG(ERROR) << "Found \"" << value << "\" instead of boolean option";
79 return default_value;
80 }
81
get_option_integer(Slice name,int64 default_value) const82 int64 ConfigShared::get_option_integer(Slice name, int64 default_value) const {
83 auto str_value = get_option(name);
84 if (str_value.empty()) {
85 return default_value;
86 }
87 if (str_value[0] != 'I') {
88 LOG(ERROR) << "Found \"" << str_value << "\" instead of integer option";
89 return default_value;
90 }
91 return to_integer<int64>(str_value.substr(1));
92 }
93
get_option_string(Slice name,string default_value) const94 string ConfigShared::get_option_string(Slice name, string default_value) const {
95 auto str_value = get_option(name);
96 if (str_value.empty()) {
97 return default_value;
98 }
99 if (str_value[0] != 'S') {
100 LOG(ERROR) << "Found \"" << str_value << "\" instead of string option";
101 return default_value;
102 }
103 return str_value.substr(1);
104 }
105
get_option_value(Slice name) const106 tl_object_ptr<td_api::OptionValue> ConfigShared::get_option_value(Slice name) const {
107 return get_option_value_object(get_option(name));
108 }
109
set_option(Slice name,Slice value)110 bool ConfigShared::set_option(Slice name, Slice value) {
111 if (value.empty()) {
112 return config_pmc_->erase(name.str()) != 0;
113 } else {
114 return config_pmc_->set(name.str(), value.str()) != 0;
115 }
116 }
117
get_option_value_object(Slice value)118 tl_object_ptr<td_api::OptionValue> ConfigShared::get_option_value_object(Slice value) {
119 if (value.empty()) {
120 return make_tl_object<td_api::optionValueEmpty>();
121 }
122
123 switch (value[0]) {
124 case 'B':
125 if (value == "Btrue") {
126 return make_tl_object<td_api::optionValueBoolean>(true);
127 }
128 if (value == "Bfalse") {
129 return make_tl_object<td_api::optionValueBoolean>(false);
130 }
131 break;
132 case 'I':
133 return make_tl_object<td_api::optionValueInteger>(to_integer<int64>(value.substr(1)));
134 case 'S':
135 return make_tl_object<td_api::optionValueString>(value.substr(1).str());
136 }
137
138 return make_tl_object<td_api::optionValueString>(value.str());
139 }
140
on_option_updated(Slice name) const141 void ConfigShared::on_option_updated(Slice name) const {
142 if (callback_ != nullptr) {
143 callback_->on_option_updated(name.str(), get_option(name));
144 }
145 }
146
147 } // namespace td
148