1 // Aseprite Config Library
2 // Copyright (c) 2014-2017 David Capello
3 //
4 // This file is released under the terms of the MIT license.
5 // Read LICENSE.txt for more information.
6 
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10 
11 #include "cfg/cfg.h"
12 
13 #include "base/file_handle.h"
14 #include "base/string.h"
15 
16 #include <cstdlib>
17 #include <iostream>
18 #include <list>
19 
20 #include "SimpleIni.h"
21 
22 #include "base/log.h"
23 
24 namespace cfg {
25 
26 class CfgFile::CfgFileImpl {
27 public:
filename() const28   const std::string& filename() const {
29     return m_filename;
30   }
31 
getAllSections(std::vector<std::string> & sections) const32   void getAllSections(std::vector<std::string>& sections) const {
33     std::list<CSimpleIniA::Entry> sectionsList;
34     m_ini.GetAllSections(sectionsList);
35     sections.reserve(sectionsList.size());
36     for (const auto& section : sectionsList)
37       sections.push_back(section.pItem);
38   }
39 
getAllKeys(const char * section,std::vector<std::string> & keys) const40   void getAllKeys(const char* section, std::vector<std::string>& keys) const {
41     std::list<CSimpleIniA::Entry> keysList;
42     if (!m_ini.GetAllKeys(section, keysList))
43       return;
44 
45     keys.reserve(keysList.size());
46     for (const auto& k : keysList)
47       keys.push_back(k.pItem);
48   }
49 
getValue(const char * section,const char * name,const char * defaultValue) const50   const char* getValue(const char* section, const char* name, const char* defaultValue) const {
51     return m_ini.GetValue(section, name, defaultValue);
52   }
53 
getBoolValue(const char * section,const char * name,bool defaultValue) const54   bool getBoolValue(const char* section, const char* name, bool defaultValue) const {
55     return m_ini.GetBoolValue(section, name, defaultValue);
56   }
57 
getIntValue(const char * section,const char * name,int defaultValue) const58   int getIntValue(const char* section, const char* name, int defaultValue) const {
59     return m_ini.GetLongValue(section, name, defaultValue);
60   }
61 
getDoubleValue(const char * section,const char * name,double defaultValue) const62   double getDoubleValue(const char* section, const char* name, double defaultValue) const {
63     return m_ini.GetDoubleValue(section, name, defaultValue);
64   }
65 
setValue(const char * section,const char * name,const char * value)66   void setValue(const char* section, const char* name, const char* value) {
67     m_ini.SetValue(section, name, value);
68   }
69 
setBoolValue(const char * section,const char * name,bool value)70   void setBoolValue(const char* section, const char* name, bool value) {
71     m_ini.SetBoolValue(section, name, value);
72   }
73 
setIntValue(const char * section,const char * name,int value)74   void setIntValue(const char* section, const char* name, int value) {
75     m_ini.SetLongValue(section, name, value);
76   }
77 
setDoubleValue(const char * section,const char * name,double value)78   void setDoubleValue(const char* section, const char* name, double value) {
79     m_ini.SetDoubleValue(section, name, value);
80   }
81 
deleteValue(const char * section,const char * name)82   void deleteValue(const char* section, const char* name) {
83     m_ini.Delete(section, name, true);
84   }
85 
load(const std::string & filename)86   void load(const std::string& filename) {
87     m_filename = filename;
88 
89     base::FileHandle file(base::open_file(m_filename, "rb"));
90     if (file) {
91       m_ini.SetMultiLine();
92       SI_Error err = m_ini.LoadFile(file.get());
93       if (err != SI_OK) {
94         LOG(ERROR) << "CFG: Error " << err << " loading configuration from " << m_filename << "\n";
95       }
96     }
97   }
98 
save()99   void save() {
100     base::FileHandle file(base::open_file(m_filename, "wb"));
101     if (file) {
102       SI_Error err = m_ini.SaveFile(file.get());
103       if (err != SI_OK) {
104         LOG(ERROR) << "CFG: Error " << err << " saving configuration into " << m_filename << "\n";
105       }
106     }
107   }
108 
109 private:
110   std::string m_filename;
111   CSimpleIniA m_ini;
112 };
113 
CfgFile()114 CfgFile::CfgFile()
115   : m_impl(new CfgFileImpl)
116 {
117 }
118 
~CfgFile()119 CfgFile::~CfgFile()
120 {
121   delete m_impl;
122 }
123 
filename() const124 const std::string& CfgFile::filename() const
125 {
126   return m_impl->filename();
127 }
128 
getAllSections(std::vector<std::string> & sections) const129 void CfgFile::getAllSections(std::vector<std::string>& sections) const
130 {
131   m_impl->getAllSections(sections);
132 }
133 
getAllKeys(const char * section,std::vector<std::string> & keys) const134 void CfgFile::getAllKeys(const char* section, std::vector<std::string>& keys) const
135 {
136   m_impl->getAllKeys(section, keys);
137 }
138 
getValue(const char * section,const char * name,const char * defaultValue) const139 const char* CfgFile::getValue(const char* section, const char* name, const char* defaultValue) const
140 {
141   return m_impl->getValue(section, name, defaultValue);
142 }
143 
getBoolValue(const char * section,const char * name,bool defaultValue)144 bool CfgFile::getBoolValue(const char* section, const char* name, bool defaultValue)
145 {
146   return m_impl->getBoolValue(section, name, defaultValue);
147 }
148 
getIntValue(const char * section,const char * name,int defaultValue)149 int CfgFile::getIntValue(const char* section, const char* name, int defaultValue)
150 {
151   return m_impl->getIntValue(section, name, defaultValue);
152 }
153 
getDoubleValue(const char * section,const char * name,double defaultValue)154 double CfgFile::getDoubleValue(const char* section, const char* name, double defaultValue)
155 {
156   return m_impl->getDoubleValue(section, name, defaultValue);
157 }
158 
setValue(const char * section,const char * name,const char * value)159 void CfgFile::setValue(const char* section, const char* name, const char* value)
160 {
161   m_impl->setValue(section, name, value);
162 }
163 
setBoolValue(const char * section,const char * name,bool value)164 void CfgFile::setBoolValue(const char* section, const char* name, bool value)
165 {
166   m_impl->setBoolValue(section, name, value);
167 }
168 
setIntValue(const char * section,const char * name,int value)169 void CfgFile::setIntValue(const char* section, const char* name, int value)
170 {
171   m_impl->setIntValue(section, name, value);
172 }
173 
setDoubleValue(const char * section,const char * name,double value)174 void CfgFile::setDoubleValue(const char* section, const char* name, double value)
175 {
176   m_impl->setDoubleValue(section, name, value);
177 }
178 
deleteValue(const char * section,const char * name)179 void CfgFile::deleteValue(const char* section, const char* name)
180 {
181   m_impl->deleteValue(section, name);
182 }
183 
load(const std::string & filename)184 void CfgFile::load(const std::string& filename)
185 {
186   m_impl->load(filename);
187 }
188 
save()189 void CfgFile::save()
190 {
191   m_impl->save();
192 }
193 
194 } // namespace cfg
195