/common/common.hpp

https://bitbucket.org/nileshgr/cxxcms/ · C++ Header · 231 lines · 73 code · 47 blank · 111 comment · 4 complexity · 37a487d1435e47ebcbbb64bc9b454dd7 MD5 · raw file

  1. #ifndef COMMON_HPP
  2. #define COMMON_HPP
  3. #include <string>
  4. #include <global.hpp>
  5. #include <map>
  6. #include <memory>
  7. #include <algorithm>
  8. #include <cctype>
  9. /*! \file common.hpp
  10. \brief %Common utilities
  11. File contains declaration for various classes and functions commonly used. Template functions
  12. and small class methods are implemented inline
  13. */
  14. /*! \namespace Common
  15. \brief %Common functions/classes
  16. This module contains functions, classes, etc. which are common to the whole program (frequently used).
  17. */
  18. namespace Common {
  19. //! Error codes for the common namespace
  20. enum {
  21. E_CONFIG_LOAD, //!< Error while loading configuration file
  22. E_CONFIG_PARAM_NOT_FOUND, //!< Configuration parameter not found \sa Config::operator[]
  23. E_REGISTRY_ITEM_NOT_FOUND, //!< Registry item not found \sa Registry::getItem
  24. };
  25. /*! \brief Global %Exception class
  26. An instance of this class will be thrown whenever an exception/error occurs in the program code. This does not apply to
  27. exceptions thrown by STL.
  28. -Converting/casting this class to const char* will return the message
  29. -Converting/casting this class to int will return the code
  30. %Exception class won't be used very frequently, in the sense, it will be thrown only in case of error,
  31. and errors obviously must occur rarely. Hence, functions of this class aren't inlined to keep the binary size small
  32. in case the compiler inlines the code after requesition by the inline statement (or definition in the class itself).
  33. \todo Global exception handler
  34. \coder{Nilesh G,nileshgr}
  35. */
  36. class Exception {
  37. private:
  38. std::string message; //!< Message of the exception
  39. int code; //!< Error code of the exception
  40. unsigned int line; //!< Line number in the file where the exception was thrown
  41. std::string file; //!< File name in which exception was thrown
  42. public:
  43. /*! \brief Constructor
  44. \param[in] _message std::string - The message
  45. \param[in] _code int - Error code
  46. \param[in] _line unsigned int - Line number in file where exception was thrown
  47. \param[in] _file const char* - File name where exception was thrown
  48. */
  49. Exception(std::string _message, int _code = 0, unsigned int _line = 0, const char* _file = NULL);
  50. /*! \brief Object to const char* casting operator
  51. When object of Exception is casted to const char*, it returns the message value from #getCMessage
  52. \return const char* #getCMessage
  53. */
  54. operator const char*() const;
  55. /*! \brief Object to int casting operator
  56. When object of Exception is casted to int, it returns #code value from #getCode
  57. \return int #getCode
  58. */
  59. operator int() const;
  60. /*! \return The exception message excluding line number & file name (#message)
  61. \sa getCMessage
  62. */
  63. const char* getMessage() const;
  64. //! \return Error/Exception code from #code
  65. int getCode() const;
  66. //! \return Line number where exception occured from #line
  67. unsigned int getLineNo() const;
  68. //! \return File name in which exception occurred from #file
  69. const char* getFileName() const;
  70. //! \return Complete exception message in the format: [Error X] on line \#L of file F
  71. const char* getCMessage() const;
  72. };
  73. /*! \brief Configuration reader class
  74. The applications configuration will be stored in a XML file which will be parsed using pugixml into a #Dict_t.
  75. #operator[] gives access (read only) to each parameter.
  76. */
  77. class Config {
  78. private:
  79. //! Dicitonary to store parsed XML data
  80. Dict_t data;
  81. public:
  82. /*! \brief Constructor - the main function which does the parsing.
  83. The whole parsing/processing occurs in the constructor (by calling pugixml's functions).
  84. \remark The following structure is assumed in the XML file:
  85. \verbatim
  86. <config>
  87. <moduleName>
  88. <moduleParameter1>value1</moduleParameter1>
  89. <moduleParameter2>value2</moduleParameter2>
  90. .
  91. .
  92. .
  93. </moduleName>
  94. </config>
  95. \endverbatim
  96. The configuration in #data will be stored as data[moduleName_moduleParameter1] = value1
  97. \param[in] filename Path to the XML file containing configuration
  98. */
  99. Config(std::string filename);
  100. /*! \brief Element access to parsed \<keys,values\> stored in #data
  101. We don't need write access to configuration, hence the function returns a const std::string and not a reference or pointer
  102. \param[in] key Element name (xml) or key name in the configuration
  103. \return Value of the respective key in #data
  104. \throw Common::Exception with #E_CONFIG_PARAM_NOT_FOUND if key is not found in #data
  105. */
  106. const std::string operator[](std::string key) {
  107. if(data.find(key) == data.end())
  108. throw Common::Exception("Configuration parameter " + key + " not found", E_CONFIG_PARAM_NOT_FOUND, __LINE__, __FILE__);
  109. return data[key];
  110. }
  111. //! \sa #operator[]
  112. const std::string getParam(std::string key) {
  113. return data[key];
  114. }
  115. };
  116. /*! \brief Registry class
  117. A class to store pointers to various types of objects etc with key name.
  118. The class supports two interfaces- singleton and the usual, multiple instances. \n
  119. In singleton method, once an instance is created, it will be persisted till the method to destroy the instance is called.
  120. \coder{Nilesh G,nileshgr}
  121. */
  122. class Registry {
  123. private:
  124. typedef std::map<std::string, void*> items_t; //!< Define items_t dictionary type
  125. typedef std::pair<std::string, void*> item_t; //!< Define item_t, one single item type
  126. items_t items; //!< Dictionary to store pointers to objects
  127. static std::unique_ptr<Registry> instance; //!< Unique_ptr to store pointer to singleton instance
  128. public:
  129. //! Static method to obtain instance
  130. static Registry& getInstance();
  131. //! Static method to destroy instance
  132. static void destroyInstance();
  133. /*! \brief Method to add item
  134. \param name Name of item to be added
  135. \param ptr Pointer to item to be stored
  136. \return Registry& for cascading operations
  137. */
  138. Registry& addItem(std::string name, void* ptr) {
  139. std::transform(name.begin(), name.end(), name.begin(), (int (*)(int))std::tolower);
  140. items[name] = ptr;
  141. return *this;
  142. }
  143. /*! \brief Templated function to retrieve item
  144. \param name Name of item to be returned
  145. \tparam objtype Type of the object required as return type. dynamic_cast will be used.
  146. \return Reference to dynamic_cast of objtype
  147. \throw Common::Exception if name is not found in items
  148. */
  149. template<typename objtype>
  150. objtype& getItem(std::string name) {
  151. std::transform(name.begin(), name.end(), name.begin(), (int (*)(int)) std::tolower);
  152. items_t::iterator i;
  153. if((i = items.find(name)) == items.end())
  154. throw Common::Exception("Item: " + name + " not found in registry", E_REGISTRY_ITEM_NOT_FOUND, __LINE__, __FILE__);
  155. return *(reinterpret_cast <objtype*> (i->second));
  156. }
  157. /*! \brief Method to delete item
  158. \param name Name of the item to be deleted
  159. \return Registry& for cascading operations
  160. */
  161. Registry& deleteItem(std::string name) {
  162. items.erase(name);
  163. return *this;
  164. }
  165. };
  166. }
  167. #endif