* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#include "config_file.h"
#include <algorithm>
#include <fstream>
#include "util/log.h"
#include "util/util.h"
using namespace std;
namespace {
const string kConfigItemSeparator = ",";
}
namespace aicpu {
ConfigFile &ConfigFile::GetInstance() {
static ConfigFile instance;
return instance;
}
string ConfigFile::Trim(const string &source, const char delims) const {
string result(source);
string::size_type index = result.find_last_not_of(delims);
if (index != string::npos) {
result.erase(++index);
}
index = result.find_first_not_of(delims);
if (index != string::npos) {
result.erase(0, index);
}
return result;
}
aicpu::State ConfigFile::LoadFile(const string &file_name) {
if (!is_load_file_) {
std::fstream f;
f.open(file_name.c_str(), std::fstream::in);
if (!f.is_open()) {
return aicpu::State(ge::FAILED, Stringcat("open file[", file_name, "] failed"));
}
string line;
while (getline(f, line)) {
if (line.empty()) {
AICPUE_LOGI("Skip empty line");
continue;
}
string timed_line = Trim(Trim(Trim(line), '\r'), '\n');
if (timed_line[0] == '#') {
AICPUE_LOGI("Skip annotation line %s", timed_line.c_str());
continue;
}
auto pos_trenner = timed_line.find('=');
if (pos_trenner == string::npos) {
AICPU_REPORT_INNER_ERR_MSG(
"invalid item[%s], should be contain '=', file[%s]",
timed_line.c_str(), file_name.c_str());
continue;
}
string key = Trim(timed_line.substr(0, pos_trenner));
if (data_map_.find(key) != data_map_.end()) {
AICPUE_LOGW("repeated key %s.", key.c_str());
continue;
}
string value = Trim(timed_line.substr(pos_trenner + 1));
data_map_[key] = value;
}
f.close();
if (data_map_.empty()) {
return aicpu::State(ge::FAILED, Stringcat("cannot parse out the normative",
" configuration k-v items from file[", file_name, "]"));
}
is_load_file_ = true;
}
return aicpu::State(ge::SUCCESS);
}
bool ConfigFile::GetValue(const string &key, string &value) const {
auto iter = data_map_.find(key);
if (iter == data_map_.end()) {
return false;
}
value = iter->second;
return true;
}
void ConfigFile::SetValue(const string &key, string &value) {
auto iter = data_map_.find(key);
if (iter != data_map_.end()) {
data_map_[key] = value;
}
}
void ConfigFile::SplitValue(const string &str, vector<string> &result,
const set<string> &blacklist) const {
string strs = str + kConfigItemSeparator;
size_t pos = strs.find(kConfigItemSeparator);
size_t size = strs.size();
while (pos != string::npos) {
string x = strs.substr(0, pos);
if (!x.empty() && blacklist.find(x) == blacklist.end()) {
auto it = find(result.begin(), result.end(), x);
if (it == result.end()) {
result.push_back(x);
}
}
strs = strs.substr(pos + kConfigItemSeparator.length(), size);
pos = strs.find(kConfigItemSeparator);
}
}
}