PageRenderTime 42ms CodeModel.GetById 21ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

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