/* @file config_store.cpp * @brief ConfigStore implementation: TOML parsing, thread-safe get/set with thread-local safety. * ConfigStore 实现:TOML 解析、线程安全的 get/set(基于 thread-local 安全机制)。 * Copyright (c) 2026 dstalk contributors. GPLv3. */ #include "config_store.hpp" #include "../../plugins/config/include/toml_parse.h" #include #include #include #include namespace dstalk { // 在互斥锁下加载并解析 TOML 文件到键值存储 / Load and parse a TOML file into the key-value store under mutex. int ConfigStore::load_file(const char* path) { if (!path) return -1; std::ifstream file(path); if (!file.is_open()) return -1; std::stringstream ss; ss << file.rdbuf(); std::string data = ss.str(); // W12.2: 使用共享 TOML 解析器(从 config_plugin.cpp 去重) / Use shared TOML parser (de-duplicated from config_plugin.cpp) toml::parse(data, [this](const std::string& key, const std::string& value) { std::lock_guard lock(mutex_); data_[key] = value; }); return 0; } // 检索配置值,返回线程本地副本以避免 c_str() 悬空 / Retrieve config value, returning a thread-local copy to avoid dangling c_str(). const char* ConfigStore::get(const char* key) const { if (!key) return nullptr; std::lock_guard lock(mutex_); auto it = data_.find(key); if (it == data_.end()) return nullptr; // W12.2: 在释放锁之前复制到线程本地缓冲区 / // Copy to thread-local buffer before releasing lock. // 防止当并发 set() 触发 std::string 重新分配时 c_str() 悬空 / // Prevents c_str() dangling when concurrent set() on the same key // triggers std::string reallocation (W11.2 audit Finding 3). thread_local std::string tls_cached; tls_cached = it->second; return tls_cached.c_str(); } // 以 std::string 值类型检索配置(安全的值副本)/ Retrieve config value as an owned std::string (safe by-value copy). std::string ConfigStore::get_copy(const char* key) const { if (!key) return {}; std::lock_guard lock(mutex_); auto it = data_.find(key); if (it == data_.end()) return {}; return it->second; // 在锁下复制构造,始终安全 / copy-constructed under lock, always safe } // 在锁下设置配置键值对 / Set a config key-value pair under lock. int ConfigStore::set(const char* key, const char* value) { if (!key || !value) return -1; std::lock_guard lock(mutex_); data_[key] = value; return 0; } } // namespace dstalk