15 #include "fcitx-utils/macros.h" 16 #include "fcitx-utils/misc_p.h" 23 :
QPtrHolder(q), name_(std::move(_name)), lineNumber_(0) {}
25 :
QPtrHolder(q), value_(other.value_), comment_(other.comment_),
26 lineNumber_(other.lineNumber_) {}
35 auto value = other.value_;
36 auto comment = other.comment_;
37 auto lineNumber = other.lineNumber_;
38 OrderedMap<std::string, std::shared_ptr<RawConfig>> newSubItems;
39 for (
const auto &item : other.subItems_) {
40 auto result = newSubItems[item.first] =
41 q_func()->createSub(item.second->name());
42 *result = *item.second;
44 value_ = std::move(value);
45 comment_ = std::move(comment);
46 lineNumber_ = lineNumber;
48 subItems_ = std::move(newSubItems);
52 std::shared_ptr<RawConfig> getNonexistentRawConfig(
RawConfig *q,
53 const std::string &key) {
54 auto result = subItems_[key] = q->createSub(key);
58 static std::shared_ptr<const RawConfig>
59 getNonexistentRawConfig(
const RawConfig * ,
60 const std::string & ) {
64 template <
typename T,
typename U>
65 static std::shared_ptr<T>
66 getRawConfigHelper(T &that,
const std::string &path, U callback) {
68 std::shared_ptr<T> result;
69 for (std::string::size_type pos = 0, new_pos = path.find(
'/', pos);
70 pos != std::string::npos && cur;
71 pos = ((std::string::npos == new_pos) ? new_pos : (new_pos + 1)),
72 new_pos = path.find(
'/', pos)) {
73 auto key = path.substr(pos, (std::string::npos == new_pos)
76 auto iter = cur->d_func()->subItems_.find(key);
77 if (iter == cur->d_func()->subItems_.end()) {
78 result = cur->d_func()->getNonexistentRawConfig(cur, key);
80 result = iter->second;
85 callback(*cur, path.substr(0, new_pos));
94 std::function<
bool(T &,
const std::string &path)> callback,
95 bool recursive,
const std::string &pathPrefix) {
96 auto d = that.d_func();
97 for (
const auto &pair : d->subItems_) {
98 std::shared_ptr<T> item = pair.second;
99 auto newPathPrefix = pathPrefix.empty()
101 : pathPrefix +
"/" + item->name();
102 if (!callback(*item, newPathPrefix)) {
106 if (!visitHelper(*item, callback, recursive, newPathPrefix)) {
114 void detachSubItems() {
115 for (
const auto &pair : subItems_) {
116 pair.second->d_func()->parent_ =
nullptr;
121 const std::string name_;
123 std::string comment_;
124 OrderedMap<std::string, std::shared_ptr<RawConfig>> subItems_;
125 unsigned int lineNumber_;
128 RawConfig::RawConfig() :
RawConfig(
"") {}
130 RawConfig::RawConfig(std::string name)
131 : d_ptr(std::make_unique<RawConfigPrivate>(
this, std::move(name))) {}
133 RawConfig::~RawConfig() {
138 RawConfig::RawConfig(
const RawConfig &other)
139 : d_ptr(std::make_unique<RawConfigPrivate>(
this, *other.d_ptr)) {
140 for (
const auto &item : other.d_func()->subItems_) {
141 *
get(item.first,
true) = *item.second;
145 *d_ptr = *other.d_ptr;
149 std::shared_ptr<RawConfig> RawConfig::get(
const std::string &path,
151 auto dummy = [](
const RawConfig &,
const std::string &) {};
153 return RawConfigPrivate::getRawConfigHelper(*
this, path, dummy);
155 return std::const_pointer_cast<
RawConfig>(
156 RawConfigPrivate::getRawConfigHelper<const RawConfig>(*
this, path,
160 std::shared_ptr<const RawConfig> RawConfig::get(
const std::string &path)
const {
161 auto dummy = [](
const RawConfig &,
const std::string &) {};
162 return RawConfigPrivate::getRawConfigHelper(*
this, path, dummy);
165 bool RawConfig::remove(
const std::string &path) {
166 auto pos = path.rfind(
'/');
168 if (pos == 0 || pos + 1 == path.size()) {
172 if (pos != std::string::npos) {
173 root =
get(path.substr(0, pos)).
get();
175 return root->d_func()->subItems_.erase(path.substr(pos + 1)) > 0;
178 void RawConfig::removeAll() {
180 d->subItems_.clear();
183 void RawConfig::setValue(std::string value) {
185 d->value_ = std::move(value);
188 void RawConfig::setComment(std::string comment) {
190 d->comment_ = std::move(comment);
193 void RawConfig::setLineNumber(
unsigned int lineNumber) {
195 d->lineNumber_ = lineNumber;
198 const std::string &RawConfig::name()
const {
203 const std::string &RawConfig::comment()
const {
208 const std::string &RawConfig::value()
const {
213 unsigned int RawConfig::lineNumber()
const {
215 return d->lineNumber_;
218 bool RawConfig::hasSubItems()
const {
220 return !d->subItems_.empty();
223 size_t RawConfig::subItemsSize()
const {
225 return d->subItems_.size();
228 std::vector<std::string> RawConfig::subItems()
const {
230 std::vector<std::string> result;
231 result.reserve(d->subItems_.size());
232 for (
const auto &pair : d->subItems_) {
233 result.push_back(pair.first);
243 std::shared_ptr<RawConfig> RawConfig::detach() {
248 auto ref = d->parent_->get(d->name_);
249 d->parent_->d_func()->subItems_.erase(d->name_);
250 d->parent_ =
nullptr;
254 bool RawConfig::visitSubItems(
255 std::function<
bool(
RawConfig &,
const std::string &path)> callback,
256 const std::string &path,
bool recursive,
const std::string &pathPrefix) {
258 std::shared_ptr<RawConfig> subItem;
261 root = subItem.get();
268 return RawConfigPrivate::visitHelper(*root, std::move(callback), recursive,
272 bool RawConfig::visitSubItems(
273 std::function<
bool(
const RawConfig &,
const std::string &path)> callback,
274 const std::string &path,
bool recursive,
275 const std::string &pathPrefix)
const {
276 const auto *root =
this;
277 std::shared_ptr<const RawConfig> subItem;
280 root = subItem.get();
287 return RawConfigPrivate::visitHelper(*root, std::move(callback), recursive,
291 void RawConfig::visitItemsOnPath(
292 std::function<
void(
RawConfig &,
const std::string &path)> callback,
293 const std::string &path) {
294 RawConfigPrivate::getRawConfigHelper(*
this, path, std::move(callback));
296 void RawConfig::visitItemsOnPath(
297 std::function<
void(
const RawConfig &,
const std::string &path)> callback,
298 const std::string &path)
const {
299 RawConfigPrivate::getRawConfigHelper(*
this, path, std::move(callback));
302 std::shared_ptr<RawConfig> RawConfig::createSub(std::string name) {
304 RawSubConfig(
RawConfig *parent, std::string name)
310 return std::make_shared<RawSubConfig>(
this, std::move(name));
314 log <<
"RawConfig(=" << config.value();
315 config.visitSubItems(
316 [&log](
const RawConfig &subConfig,
const std::string &path) {
317 log <<
", " << path <<
"=" << subConfig.value();