blob: 7c4b9495e4606d9ab1c0c639a693fc1c907a710a [file] [log] [blame]
/*
* Copyright 2020 The casbin Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "casbin/pch.h"
#ifndef CONFIG_CPP
#define CONFIG_CPP
#include "casbin/config/config.h"
#include "casbin/exception/illegal_argument_exception.h"
#include "casbin/exception/io_exception.h"
#include "casbin/util/util.h"
namespace casbin {
const std::string Config::DEFAULT_SECTION = "default";
const std::string Config::DEFAULT_COMMENT = "#";
const std::string Config::DEFAULT_COMMENT_SEM = ";";
std::mutex Config::mtx_lock;
/**
* addConfig adds a new section->key:value to the configuration.
*/
bool Config::AddConfig(std::string section, const std::string& option, const std::string& value) {
if (!section.compare(""))
section = DEFAULT_SECTION;
bool ok = data[section].find(option) != data[section].end();
data[section][option] = value;
return !ok;
}
void Config::Parse(const std::string& f_name) {
mtx_lock.lock();
std::ifstream infile;
try {
infile.open(f_name);
} catch (const std::ifstream::failure e) {
mtx_lock.unlock();
throw IOException("Cannot open file.");
}
ParseBuffer(&infile);
mtx_lock.unlock();
infile.close();
}
void Config::ParseBuffer(std::istream* buf) {
std::string section = "";
int line_num = 0;
std::string line;
while (true) {
line_num++;
if (getline(*buf, line, '\n')) {
if (!line.compare(""))
continue;
} else
break;
line = Trim(line);
if (line.find(DEFAULT_COMMENT) == 0)
continue;
else if (line.find(DEFAULT_COMMENT_SEM) == 0)
continue;
else if (line.find("[") == 0 && EndsWith(line, "]"))
section = line.substr(1, line.length() - 2);
else {
std::vector<std::string> option_val = Split(line, "=", 2);
if (option_val.size() != 2) {
std::string error = "parse the content error : line " + std::to_string(line_num) + " , " + option_val[0] + " = ?";
throw IllegalArgumentException(error);
}
std::string option = Trim(option_val[0]);
std::string value = Trim(option_val[1]);
AddConfig(section, option, value);
}
}
}
/**
* newConfig create an empty configuration representation from file.
*
* @param confName the path of the model file.
* @return the constructor of Config.
*/
std::shared_ptr<Config> Config::NewConfig(const std::string& conf_name) {
std::shared_ptr<Config> c = std::make_shared<Config>();
c->Parse(conf_name);
return c;
}
/**
* newConfigFromText create an empty configuration representation from text.
*
* @param text the model text.
* @return the constructor of Config.
*/
std::shared_ptr<Config> Config::NewConfigFromText(const std::string& text) {
std::shared_ptr<Config> c = std::make_shared<Config>();
std::stringstream stream(text);
c->ParseBuffer(&stream);
return c;
}
Config::Config() {
}
Config::Config(const std::string& conf_name) {
this->Parse(conf_name);
}
bool Config::GetBool(std::string_view key) {
return Get(key).compare("true") == 0;
}
int Config::GetInt(std::string_view key) {
return atoi(Get(key).c_str());
}
float Config::GetFloat(std::string_view key) {
return float(atof(Get(key).c_str()));
}
std::string Config::GetString(std::string_view key) {
return Get(key);
}
std::vector<std::string> Config::GetStrings(std::string_view key) {
std::string v = Get(key);
if (!v.compare(""))
return {};
return Split(v, ",");
}
void Config::Set(std::string_view key, const std::string& value) {
mtx_lock.lock();
if (key.length() == 0) {
mtx_lock.unlock();
throw IllegalArgumentException("key is empty");
}
std::string section = "";
std::string option;
std::vector<std::string> keys = Split(std::string(key), "::");
if (keys.size() >= 2) {
section = keys[0];
option = keys[1];
} else
option = keys[0];
AddConfig(section, option, value);
mtx_lock.unlock();
}
std::string Config::Get(std::string_view key) {
std::string section;
std::string option;
std::vector<std::string> keys = Split(std::string(key), "::");
if (keys.size() >= 2) {
section = keys[0];
option = keys[1];
} else {
section = DEFAULT_SECTION;
option = keys[0];
}
bool ok = data.find(section) != data.end() && data[section].find(option) != data[section].end();
if (ok)
return data[section][option];
return "";
}
} // namespace casbin
#endif // CONFIG_CPP