summaryrefslogtreecommitdiff
path: root/src/config/config.cpp
blob: 5f937e61da462de988a0ae782e596ff1e5ab8879 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <utils/make_unique.hpp>
#include <config/config.hpp>

#include <iostream>
#include <sstream>

#include <stdlib.h>

std::string Config::filename = "./biboumi.cfg";
bool Config::file_must_exist = false;

std::string Config::get(const std::string& option, const std::string& def)
{
  Config* self = Config::instance().get();
  auto it = self->values.find(option);

  if (it == self->values.end())
    return def;
  return it->second;
}

int Config::get_int(const std::string& option, const int& def)
{
  Config* self = Config::instance().get();
  std::string res = self->get(option, "");
  if (!res.empty())
    return atoi(res.c_str());
  else
    return def;
}

void Config::set_int(const std::string& option, const int& value, bool save)
{
  std::ostringstream os;
  os << value;
  Config::set(option, os.str(), save);
}

void Config::set(const std::string& option, const std::string& value, bool save)
{
  Config* self = Config::instance().get();
  self->values[option] = value;
  if (save)
    {
      self->save_to_file();
      self->trigger_configuration_change();
    }
}

void Config::connect(t_config_changed_callback callback)
{
  Config* self = Config::instance().get();
  self->callbacks.push_back(callback);
}

void Config::close()
{
  Config* self = Config::instance().get();
  self->save_to_file();
  self->values.clear();
  Config::instance().reset();
}

/**
 * Private methods
 */

void Config::trigger_configuration_change()
{
  std::vector<t_config_changed_callback>::iterator it;
  for (it = this->callbacks.begin(); it < this->callbacks.end(); ++it)
      (*it)();
}

std::unique_ptr<Config>& Config::instance()
{
  static std::unique_ptr<Config> instance;

  if (!instance)
    {
      instance = std::make_unique<Config>();
      instance->read_conf();
    }
  return instance;
}

bool Config::read_conf()
{
  std::ifstream file;
  file.open(filename.data());
  if (!file.is_open())
    {
      if (Config::file_must_exist)
        {
          perror(("Error while opening file " + filename + " for reading.").c_str());
          file.exceptions(std::ifstream::failbit);
        }
      return false;
    }

  std::string line;
  size_t pos;
  std::string option;
  std::string value;
  while (file.good())
    {
      std::getline(file, line);
      if (line == "" || line[0] == '#')
        continue ;
      pos = line.find('=');
      if (pos == std::string::npos)
        continue ;
      option = line.substr(0, pos);
      value = line.substr(pos+1);
      this->values[option] = value;
    }
  return true;
}

void Config::save_to_file() const
{
  std::ofstream file(this->filename.data());
  if (file.fail())
    {
      std::cerr << "Could not save config file." << std::endl;
      return ;
    }
  for (auto& it: this->values)
    file << it.first << "=" << it.second << std::endl;
  file.close();
}