inicpp
C++ parser of INI files with schema validation.
option_schema.cpp
1 #include "option_schema.h"
2 #include "string_utils.h"
3 
4 namespace inicpp
5 {
7  {
8  this->operator=(source);
9  }
10 
12  {
13  type_ = source.type_;
14 
15  switch (type_) {
16  case option_type::boolean_e: params_ = copy_schema<boolean_ini_t>(source.params_); break;
17  case option_type::enum_e: params_ = copy_schema<enum_ini_t>(source.params_); break;
18  case option_type::float_e: params_ = copy_schema<float_ini_t>(source.params_); break;
19  case option_type::signed_e: params_ = copy_schema<signed_ini_t>(source.params_); break;
20  case option_type::string_e: params_ = copy_schema<string_ini_t>(source.params_); break;
21  case option_type::unsigned_e: params_ = copy_schema<unsigned_ini_t>(source.params_); break;
22  case option_type::invalid_e:
23  // never reached
24  throw invalid_type_exception("Invalid option type");
25  break;
26  }
27 
28  return *this;
29  }
30 
32  {
33  this->operator=(std::move(source));
34  }
35 
37  {
38  if (this != &source) {
39  type_ = source.type_;
40  params_ = std::move(source.params_);
41  }
42  return *this;
43  }
44 
45  const std::string &option_schema::get_name() const
46  {
47  return params_->name;
48  }
49 
50  option_type option_schema::get_type() const
51  {
52  return type_;
53  }
54 
56  {
57  return params_->type == option_item::list;
58  }
59 
60  const std::string &option_schema::get_default_value() const
61  {
62  return params_->default_value;
63  }
64 
66  {
67  return params_->requirement == item_requirement::mandatory;
68  }
69 
70  const std::string &option_schema::get_comment() const
71  {
72  return params_->comment;
73  }
74 
76  {
77  if (params_->type == option_item::single && opt.is_list()) {
78  throw validation_exception("Option '" + opt.get_name() + "' - list given, single value expected");
79  } else if (params_->type == option_item::list && !opt.is_list()) {
80  throw validation_exception("Option '" + opt.get_name() + "' - single value given, list expected");
81  }
82 
83  // if option type doesn't match, parse it to proper one
84  if (opt.get_type() != type_) {
85  parse_option_items(opt);
86  }
87 
88  // validate range using provided validator
89  validate_option_items(opt);
90  }
91 
92  void option_schema::validate_option_items(option &opt) const
93  {
94  // load value and call validate function on it
95  switch (type_) {
96  case option_type::boolean_e:
97  validate_typed_option_items<boolean_ini_t>(opt.get_list<boolean_ini_t>(), opt.get_name());
98  break;
99  case option_type::enum_e:
100  validate_typed_option_items<enum_ini_t>(opt.get_list<enum_ini_t>(), opt.get_name());
101  break;
102  case option_type::float_e:
103  validate_typed_option_items<float_ini_t>(opt.get_list<float_ini_t>(), opt.get_name());
104  break;
105  case option_type::signed_e:
106  validate_typed_option_items<signed_ini_t>(opt.get_list<signed_ini_t>(), opt.get_name());
107  break;
108  case option_type::string_e:
109  validate_typed_option_items<string_ini_t>(opt.get_list<string_ini_t>(), opt.get_name());
110  break;
111  case option_type::unsigned_e:
112  validate_typed_option_items<unsigned_ini_t>(opt.get_list<unsigned_ini_t>(), opt.get_name());
113  break;
114  case option_type::invalid_e:
115  // never reached
116  throw invalid_type_exception("Option '" + opt.get_name() + "' - invalid option type");
117  break;
118  }
119  }
120 
121  void option_schema::parse_option_items(option &opt) const
122  {
123  switch (type_) {
124  case option_type::boolean_e:
125  opt.set_list<boolean_ini_t>(parse_typed_option_items<boolean_ini_t>(
126  opt.get_list<string_ini_t>(), string_utils::parse_string<boolean_ini_t>, opt.get_name()));
127  break;
128  case option_type::enum_e:
129  opt.set_list<enum_ini_t>(parse_typed_option_items<enum_ini_t>(
130  opt.get_list<string_ini_t>(), string_utils::parse_string<enum_ini_t>, opt.get_name()));
131  break;
132  case option_type::float_e:
133  opt.set_list<float_ini_t>(parse_typed_option_items<float_ini_t>(
134  opt.get_list<string_ini_t>(), string_utils::parse_string<float_ini_t>, opt.get_name()));
135  break;
136  case option_type::signed_e:
137  opt.set_list<signed_ini_t>(parse_typed_option_items<signed_ini_t>(
138  opt.get_list<string_ini_t>(), string_utils::parse_string<signed_ini_t>, opt.get_name()));
139  break;
140  case option_type::string_e:
141  // string doesn't need to be parsed
142  break;
143  case option_type::unsigned_e:
144  opt.set_list<unsigned_ini_t>(parse_typed_option_items<unsigned_ini_t>(
145  opt.get_list<string_ini_t>(), string_utils::parse_string<unsigned_ini_t>, opt.get_name()));
146  break;
147  case option_type::invalid_e:
148  // never reached
149  throw invalid_type_exception("Option '" + opt.get_name() + "' - invalid option type");
150  break;
151  }
152  }
153 
154  std::ostream &option_schema::write_additional_info(std::ostream &os) const
155  {
156  // write comment
157  auto comment_lines = string_utils::split(get_comment(), '\n');
158  for (auto &comment_line : comment_lines) {
159  os << ";" << comment_line << std::endl;
160  }
161 
162  // optional/mandatory and single/list
163  std::string info_line = is_mandatory() ? "mandatory" : "optional";
164  info_line += ", ";
165  info_line += is_list() ? "list" : "single";
166  os << ";<" << info_line << ">" << std::endl;
167 
168  // default value given at construction
169  os << ";<default value: \"" << get_default_value() << "\">" << std::endl;
170 
171  return os;
172  }
173 
174  std::ostream &operator<<(std::ostream &os, const option_schema &opt_schema)
175  {
176  // write additional information about given option
177  opt_schema.write_additional_info(os);
178 
179  // write name and default value
180  os << opt_schema.get_name() << " = " << opt_schema.get_default_value() << std::endl;
181 
182  return os;
183  }
184 }
bool is_list() const
Definition: option.cpp:143
float_ini_t parse_string< float_ini_t >(const std::string &value, const std::string &option_name)
signed_ini_t parse_string< signed_ini_t >(const std::string &value, const std::string &option_name)
void validate_option(option &opt) const
const std::string & get_name() const
option_schema & operator=(const option_schema &source)
const std::string & get_comment() const
Definition: config.h:15
const std::string & get_name() const
Definition: option.cpp:67
std::vector< ReturnType > get_list() const
Definition: option.h:350
void set_list(const std::vector< ValueType > &list)
Definition: option.h:333
option_type get_type() const
option_type get_type() const
Definition: option.cpp:72
bool is_mandatory() const
INICPP_API friend std::ostream & operator<<(std::ostream &os, const option_schema &opt_schema)
unsigned_ini_t parse_string< unsigned_ini_t >(const std::string &value, const std::string &option_name)
const std::string & get_default_value() const
std::vector< std::string > split(const std::string &str, char delim)
enum_ini_t parse_string< enum_ini_t >(const std::string &value, const std::string &option_name)
boolean_ini_t parse_string< boolean_ini_t >(const std::string &value, const std::string &option_name)
std::ostream & write_additional_info(std::ostream &os) const