// toml_config.cpp
#include <cstdio>
#include "toml_config.h"
TomlConfig::TomlConfig( void )
{
loaded_ = false;
}
TomlConfig::TomlConfig( const char *fname )
{
loaded_ = false;
load(fname);
}
TomlConfig::~TomlConfig( void )
{
release();
}
bool TomlConfig::load( const char *fname )
{
release();
try {
root_ = toml::parse<toml::ordered_type_config>(fname);
} catch( const std::exception &e ) {
// 構文エラー時はtoml11が行番号と位置指示付きのメッセージを生成する
fprintf(stderr, "TomlConfig::load: %s\n", e.what());
return false;
}
loaded_ = true;
return true;
}
void TomlConfig::release( void )
{
root_ = Value();
loaded_ = false;
}
bool TomlConfig::isLoaded( void ) const
{
return loaded_;
}
int TomlConfig::getSectionNum( void ) const
{
if( !loaded_||!root_.is_table() ) {
return 0;
}
const auto &tbl = root_.as_table();
int n = 0;
for( auto it=tbl.begin(); it!=tbl.end(); ++it ) {
if( it->second.is_table() ) {
n++;
}
}
return n;
}
std::string TomlConfig::getSectionName( int idx ) const
{
if( loaded_&&root_.is_table() ) {
const auto &tbl = root_.as_table();
int n = 0;
for( auto it=tbl.begin(); it!=tbl.end(); ++it ) {
if( it->second.is_table() ) {
if( n==idx ) {
return it->first;
}
n++;
}
}
}
fprintf(stderr, "TomlConfig::getSectionName: out of range idx=%d (num=%d)\n",
idx, getSectionNum());
return "";
}
bool TomlConfig::hasSection( const char *section ) const
{
return findSec(section)!=NULL;
}
bool TomlConfig::hasKey( const char *section, const char *key ) const
{
return findVal(section, key)!=NULL;
}
int TomlConfig::getKeyNum( const char *section ) const
{
const Value *sec = findSec(section);
if( sec==NULL ) {
return 0;
}
return (int)sec->as_table().size();
}
std::string TomlConfig::getKeyName( const char *section, int idx ) const
{
const Value *sec = findSec(section);
if( sec!=NULL ) {
const auto &tbl = sec->as_table();
int n = 0;
for( auto it=tbl.begin(); it!=tbl.end(); ++it ) {
if( n==idx ) {
return it->first;
}
n++;
}
}
fprintf(stderr, "TomlConfig::getKeyName: out of range [%s] idx=%d\n", section, idx);
return "";
}
int TomlConfig::getInt( const char *section, const char *key, int defval ) const
{
const Value *v = findVal(section, key);
if( v==NULL ) {
return defval;
}
if( v->is_integer() ) {
return (int)v->as_integer();
}
if( v->is_boolean() ) {
return v->as_boolean() ? 1 : 0;
}
fprintf(stderr, "TomlConfig::getInt: [%s] %s is not an integer, use default %d\n",
section, key, defval);
return defval;
}
std::string TomlConfig::getStr( const char *section, const char *key, const char *defval ) const
{
const Value *v = findVal(section, key);
if( v==NULL ) {
return defval;
}
if( v->is_string() ) {
return v->as_string();
}
if( v->is_integer() ) {
return std::to_string(v->as_integer());
}
if( v->is_floating() ) {
return std::to_string(v->as_floating());
}
if( v->is_boolean() ) {
return v->as_boolean() ? "true" : "false";
}
fprintf(stderr, "TomlConfig::getStr: [%s] %s is not a string, use default \"%s\"\n",
section, key, defval);
return defval;
}
const TomlConfig::Value *TomlConfig::findSec( const char *section ) const
{
if( !loaded_||!root_.is_table() ) {
return NULL;
}
const auto &tbl = root_.as_table();
for( auto it=tbl.begin(); it!=tbl.end(); ++it ) {
if( it->first==section&&it->second.is_table() ) {
return &it->second;
}
}
return NULL;
}
const TomlConfig::Value *TomlConfig::findVal( const char *section, const char *key ) const
{
const Value *sec = findSec(section);
if( sec==NULL ) {
return NULL;
}
const auto &tbl = sec->as_table();
for( auto it=tbl.begin(); it!=tbl.end(); ++it ) {
if( it->first==key ) {
return &it->second;
}
}
return NULL;
}