key.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*!
  2. *\file
  3. */
  4. // Config Class
  5. // Author: Charles Gruenwald III
  6. #include "key.hpp"
  7. #include <iostream>
  8. #include <boost/version.hpp>
  9. #include <boost/lexical_cast.hpp>
  10. #include <boost/algorithm/string.hpp>
  11. #if (BOOST_VERSION==103500)
  12. # include <boost/spirit/core.hpp>
  13. using namespace boost::spirit;
  14. #else
  15. # include <boost/spirit/include/classic_core.hpp>
  16. using namespace boost::spirit::classic;
  17. #endif
  18. namespace config
  19. {
  20. // Like int_p, but support up to SInt64
  21. typedef int_parser<SInt64, 10, 1, -1> long_parser_t;
  22. static long_parser_t long_p;
  23. template <class V>
  24. Key::Key(const String & parentPath_, const String & name_, const V & value_)
  25. :
  26. m_name(name_),
  27. m_value(boost::lexical_cast<String>(value_)),
  28. m_parentPath(parentPath_),
  29. m_type(DetermineType(m_value))
  30. {
  31. }
  32. template<> Key::Key(const String & parentPath_, const String & name_, const String & value_)
  33. :
  34. m_name(name_),
  35. m_value(value_),
  36. m_parentPath(parentPath_),
  37. m_type(DetermineType(m_value))
  38. {
  39. }
  40. template Key::Key(const String &, const String &, const SInt64 &);
  41. template Key::Key(const String &, const String &, const double &);
  42. //Determine the type of a given key by trying to cast it to different types
  43. //and catching the error.
  44. unsigned short Key::DetermineType(String value)
  45. {
  46. //strings are always valid
  47. unsigned short valid = TYPE_STRING_VALID;
  48. // Try for floats
  49. if(parse(value.c_str(),real_p).full)
  50. {
  51. try
  52. {
  53. m_value_f = boost::lexical_cast<double>(value);
  54. valid |= TYPE_FLOAT_VALID;
  55. }
  56. catch(const boost::bad_lexical_cast &)
  57. {
  58. }
  59. }
  60. // and ints
  61. if(parse(value.c_str(),long_p).full)
  62. {
  63. try
  64. {
  65. m_value_i = boost::lexical_cast<SInt64>(value);
  66. valid |= TYPE_INT_VALID;
  67. }
  68. catch(const boost::bad_lexical_cast &)
  69. {
  70. }
  71. }
  72. // and bools
  73. String icase_value = m_value;
  74. boost::to_lower(icase_value);
  75. if(icase_value == "true" || icase_value == "yes" || icase_value == "1")
  76. {
  77. valid |= TYPE_BOOL_VALID;
  78. m_value_b = true;
  79. }
  80. else if(icase_value == "false" || icase_value == "no" || icase_value == "0")
  81. {
  82. valid |= TYPE_BOOL_VALID;
  83. m_value_b = false;
  84. }
  85. return valid;
  86. }
  87. void __attribute__((noreturn)) Key::throwInvalid(String type) const
  88. {
  89. if (m_value == "")
  90. std::cerr << "[SNIPER] " << "Required configuration value missing for key " << m_parentPath << "/" << m_name << std::endl;
  91. else
  92. std::cerr << "[SNIPER] " << "Invalid configuration value of type " << type << " for key " << m_parentPath << "/" << m_name << ": " << m_value << std::endl;
  93. throw std::bad_cast();
  94. }
  95. bool Key::getBool() const
  96. {
  97. if(m_type & TYPE_BOOL_VALID)
  98. return m_value_b;
  99. else
  100. throwInvalid("bool");
  101. }
  102. SInt64 Key::getInt() const
  103. {
  104. if(m_type & TYPE_INT_VALID)
  105. return m_value_i;
  106. else
  107. throwInvalid("int");
  108. }
  109. const String Key::getString() const
  110. {
  111. return m_value;
  112. }
  113. double Key::getFloat() const
  114. {
  115. if(m_type & TYPE_FLOAT_VALID)
  116. return m_value_f;
  117. else
  118. throwInvalid("float");
  119. }
  120. void Key::getValue(bool &bool_val) const
  121. {
  122. bool_val = getBool();
  123. }
  124. void Key::getValue(SInt64 &int_val) const
  125. {
  126. int_val = getInt();
  127. }
  128. void Key::getValue(String &string_val) const
  129. {
  130. string_val = getString();
  131. }
  132. void Key::getValue(double &double_val) const
  133. {
  134. double_val = getFloat();
  135. }
  136. }//end of namespace config