libcrn  3.9.5
A document image processing library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRNConfigurationFile.cpp
Go to the documentation of this file.
1 /* Copyright 2010-2016 CoReNum, INSA-Lyon, ENS-lyon
2  *
3  * This file is part of libcrn.
4  *
5  * libcrn is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * libcrn is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libcrn. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * file: CRNConfigurationFile.cpp
19  * \author Yann LEYDIER
20  */
21 
23 #include <CRNString.h>
24 #include <CRNData/CRNInt.h>
25 #include <CRNData/CRNReal.h>
26 #include <CRNException.h>
27 #include <CRNIO/CRNIO.h>
28 #include <CRNXml/CRNXml.h>
29 #include <CRNi18n.h>
30 #ifdef _MSC_VER
31 # include <direct.h> // for getcwd
32 # define getcwd _getcwd
33 #else
34 # include <unistd.h>
35 #endif
36 
37 using namespace crn;
38 
43 ConfigurationFile::ConfigurationFile(const String &application_name, const StringUTF8 &file_name, ConfigurationType ctype):
44  appname(application_name),
45  filename(file_name),
46  type(ctype)
47 {
48  if (file_name.IsEmpty())
49  filename = application_name.CStr();
50 }
51 
59 {
60  std::vector<Path> dirs, files;
61  char cwd[4096];
62  getcwd(cwd, 4096);
63  if (type == ConfigurationType::APP)
64  {
65  dirs.push_back(cwd);
66  dirs.push_back(GetUserDirectory());
67  dirs.push_back(CRN_CONFIG_PATH);
68  }
69  else
70  {
71  dirs.push_back(GetUserDirectory());
72  dirs.push_back(cwd);
73  dirs.push_back(CRN_CONFIG_PATH);
74  }
75  files.push_back(filename + ".xml");
76  files.push_back("_" + filename + ".xml");
77  files.push_back("." + filename + ".xml");
78 
79  data.Clear();
80  for (auto idir = dirs.begin(); (idir != dirs.end()); ++idir)
81  {
82  for (auto ifn = files.begin(); (ifn != files.end()); ++ifn)
83  {
84  Path confname(*idir);
85  confname += Path::Separator();
86  confname += *ifn;
87  CRNdout << confname.CStr() << std::endl;
88  try
89  {
90  data.Load(confname);
91  CRNdout << "Configuration loaded from: " << confname.CStr() << std::endl;
92  return confname;
93  }
94  catch (...)
95  { }
96  }
97  }
98  return "";
99 }
100 
105 {
106 #ifdef CRN_PF_ANDROID
107  const auto fname = filename + ".xml"; // MT : temp or good ?
108 #else
109  const auto fname = GetUserDirectory() / filename + ".xml";
110 #endif
111  try
112  {
113  data.Save(fname);
114  return fname;
115  }
116  catch (std::exception &ex)
117  {
118  CRNError(crn::StringUTF8(_("Cannot save configuration file: ")) + ex.what());
119  return "";
120  }
121 }
122 
128 {
129  return data[key];
130 }
131 
137 {
138  auto it(data.Find(key));
139  if (it != data.end())
140  return it->second;
141  else
142  return nullptr;
143 }
144 
149 SCObject ConfigurationFile::GetData(const String &key) const
150 {
151  Map::const_iterator it(data.Find(key));
152  if (it != data.end())
153  return it->second;
154  else
155  return nullptr;
156 }
157 
164 {
165  auto str = std::dynamic_pointer_cast<const Path>(GetData(key));
166  if (str)
167  {
168  if (str->IsRelative())
169  {
170  char cwd[4096];
171  getcwd(cwd, 4096);
172  return crn::Path{cwd} / *str;
173  }
174  else
175  return *str;
176  }
177  throw ExceptionInvalidArgument(key.CStr() + StringUTF8(_(" is not a Path.")));
178 }
179 
186 {
187  SCString str(std::dynamic_pointer_cast<const String>(GetData(key)));
188  if (str)
189  return *str;
190  throw ExceptionInvalidArgument(key.CStr() + StringUTF8(_(" is not a String.")));
191 }
192 
199 {
200  SCStringUTF8 str(std::dynamic_pointer_cast<const StringUTF8>(GetData(key)));
201  if (str)
202  return *str;
203  throw ExceptionInvalidArgument(key.CStr() + StringUTF8(_(" is not a StringUTF8.")));
204 }
205 
212 {
213  SCProp3 val(std::dynamic_pointer_cast<const Prop3>(GetData(key)));
214  if (val)
215  return *val;
216  throw ExceptionInvalidArgument(key.CStr() + StringUTF8(_(" is not a Prop3.")));
217 }
218 
224 int ConfigurationFile::GetInt(const String &key) const
225 {
226  auto val = std::dynamic_pointer_cast<const Int>(GetData(key));
227  if (val)
228  return *val;
229  throw ExceptionInvalidArgument(key.CStr() + StringUTF8(_(" is not an int.")));
230 }
231 
237 double ConfigurationFile::GetDouble(const String &key) const
238 {
239  auto val = std::dynamic_pointer_cast<const Real>(GetData(key));
240  if (val)
241  return *val;
242  throw ExceptionInvalidArgument(key.CStr() + StringUTF8(_(" is not a double.")));
243 }
244 
249 {
250 #ifdef _MSC_VER
251  crn::Path p(getenv("APPDATA"));
252 #else
253  crn::Path p(getenv("HOME"));
254  p /= ".config";
255 #endif
257  {
258  try
259  {
260  crn::IO::Mkdir(p);
261  }
262  catch (...)
263  {
264  return "";
265  }
266  }
267  p /= appname;
269  {
270  try
271  {
272  crn::IO::Mkdir(p);
273  }
274  catch (...)
275  {
276  return "";
277  }
278  }
279  return p;
280 }
281 
284  String::Initialize();
285  StringUTF8::Initialize();
286  Path::Initialize();
287  Int::Initialize();
288  Real::Initialize();
289  Prop3::Initialize();
290  Map::Initialize();
Path GetUserDirectory() const
Returns the path to the user configuration directory.
void Clear() noexcept
Empties the map.
Definition: CRNMap.h:83
iterator Find(const String &key)
Returns an iterator to a specific key.
Definition: CRNMap.h:90
SObject & operator[](const String &key)
Gets a value.
Path Load()
Loads the file.
#define _(String)
Definition: CRNi18n.h:51
const char * CStr() const
Conversion to UTF8 cstring.
Definition: CRNString.cpp:167
double GetDouble(const String &key) const
Gets a double.
SObject GetData(const String &key)
Gets a value.
static void Mkdir(const Path &name)
Creates a directory.
Definition: CRNIO.cpp:137
static char Separator() noexcept
Local directory separator.
Definition: CRNPath.cpp:42
void Load(const Path &fname)
Definition: CRNMap.cpp:282
#define CRN_END_CLASS_CONSTRUCTOR(classname)
Defines a class constructor.
Definition: CRNObject.h:198
A UTF32 character string class.
Definition: CRNString.h:61
void Save(const Path &fname) const
Definition: CRNMap.cpp:293
#define CRNdout
Definition: CRNIO.h:143
Interface class for the metric real number class.
Definition: CRNReal.h:38
const char * CStr() const noexcept
Conversion to UTF8 cstring.
bool IsEmpty() const noexcept
Checks if the string is empty.
A convenience class for file paths.
Definition: CRNPath.h:39
Path Save()
Saves the file to the user's personal space.
String GetString(const String &key) const
Gets a string.
#define CRNError(x)
Definition: CRNIO.h:147
std::map< String, SObject >::const_iterator const_iterator
const_iterator on the contents of the container
Definition: CRNMap.h:93
ConfigurationFile(const String &application_name, const StringUTF8 &file_name="", ConfigurationType ctype=ConfigurationType::APP)
Constructor.
Prop3 GetProp3(const String &key) const
Gets a Prop3.
StringUTF8 GetStringUTF8(const String &key) const
Gets a UTF8 string.
int GetInt(const String &key) const
Gets an int.
Interface class for the metric real number class.
Definition: CRNInt.h:40
static bool Access(const Path &name, int mode)
Checks rights on a file.
Definition: CRNIO.cpp:161
Data map class.
Definition: CRNMap.h:42
A character string class.
Definition: CRNStringUTF8.h:49
A ternary proposition.
Definition: CRNProp3.h:40
iterator end()
Returns an iterator after the last element.
Definition: CRNMap.h:88
Configuration file management utility class.
Path GetPath(const String &key) const
Gets a path.
Invalid argument error (e.g.: nullptr pointer)
Definition: CRNException.h:107
#define CRN_BEGIN_CLASS_CONSTRUCTOR(classname)
Defines a class constructor.
Definition: CRNObject.h:185