-rw-r--r-- | include/.gitignore | 2 | ||||
-rw-r--r-- | include/Makefile.am | 12 | ||||
-rw-r--r-- | include/konforka/basic_wrapper.h | 118 | ||||
-rw-r--r-- | include/konforka/exception.h | 203 | ||||
-rw-r--r-- | include/konforka/pointer_map.h | 105 | ||||
-rw-r--r-- | include/konforka/pqxx_pile.h | 59 | ||||
-rw-r--r-- | include/konforka/resource_pile.h | 118 | ||||
-rw-r--r-- | include/konforka/responsible_wrapper.h | 99 |
8 files changed, 716 insertions, 0 deletions
diff --git a/include/.gitignore b/include/.gitignore new file mode 100644 index 0000000..3dda729 --- a/dev/null +++ b/include/.gitignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..3e043d3 --- a/dev/null +++ b/include/Makefile.am @@ -0,0 +1,12 @@ +EXTRA_DIST = konforka/pqxx_pile.h +EXTRA_HEADERS= +if HAVE_PQXX +EXTRA_HEADERS += konforka/pqxx_pile.h +endif + +nobase_include_HEADERS = \ + konforka/exception.h \ + konforka/basic_wrapper.h konforka/responsible_wrapper.h \ + konforka/resource_pile.h \ + konforka/pointer_map.h \ + ${EXTRA_HEADERS} diff --git a/include/konforka/basic_wrapper.h b/include/konforka/basic_wrapper.h new file mode 100644 index 0000000..909f8b6 --- a/dev/null +++ b/include/konforka/basic_wrapper.h @@ -0,0 +1,118 @@ +#ifndef __KONFORKA_BASIC_WRAPPER_H +#define __KONFORKA_BASIC_WRAPPER_H + +/** + * @file + * @brief The konforka::basic_wrapper class declaration. + */ + +#include <konforka/exception.h> + +namespace konforka { + + /** + * @brief The basic wrapper class. + * + */ + template<typename T> + class basic_wrapper { + public: + /** + * The type of wrapped content. + */ + typedef T content_type; + + /** + * The content wrapped into the instance. + */ + content_type opkele; + /** + * This boolean indicates whether the object has a content + * attached to it. + */ + bool bopkele; + + /** + * Default constructors creates the object with no content + * associated with it. + */ + basic_wrapper() + : bopkele(false) { } + /** + * The constructor associates the content give with the object. + * @param o the content being attached to the object. + */ + basic_wrapper(content_type o) + : opkele(o), bopkele(true) { } + /** + * Virtual destructor doing nothing in this class. + */ + virtual ~basic_wrapper() { } + + /** + * Attaches the given content to the object. + * @param o the content being attached to the object. + */ + void attach(content_type o) { + opkele = o; + bopkele = true; + } + + /** + * Test whether the object has content attached. + * @return naturally, returns true if yes. + */ + bool is() const { + return bopkele; + } + + /** + * Throws an exception in case the object lacks content + * attached. + */ + void ensure() const { + if(!is()) + throw konforka::exception(CODEPOINT,"no content attached"); + } + + /** + * Get the content attached to the object. It would throw an + * exception if there is no content attached. + * @return reference to the content. + */ + virtual content_type& get_content() { + ensure(); + return opkele; + } + /** + * Get the content attached to the object. It would throw an + * exception if there is no content attached. + * @return const reference to the content. + */ + virtual const content_type& get_content() const { + ensure(); + return opkele; + } + + /** + * Casts the object to the reference to the content type, + * throwing an exception if there's no content associated with + * an object. + * @return reference to the content attached. + * @see get_content() + */ + operator const content_type&(void) const { return get_content(); } + /** + * Casts the object to the const reference to the content type, + * throwing an exception if there's no content associated with + * an object. + * @return reference to the content attached. + * @see get_content() + */ + operator content_type&(void) { return get_content(); } + }; + +} + +#endif /* __KONFORKA_BASIC_WRAPPER_H */ +/* vim:set ft=cpp: */ diff --git a/include/konforka/exception.h b/include/konforka/exception.h new file mode 100644 index 0000000..5e0bf96 --- a/dev/null +++ b/include/konforka/exception.h @@ -0,0 +1,203 @@ +#ifndef __KONFORKA_EXCEPTION_H +#define __KONFORKA_EXCEPTION_H + +#include <exception> +#include <string> +#include <list> + +/** + * @file + * @brief exception-related stuff. + * + * Basic exception-related declarations and definitions. + */ + +/** + * @def CODEPOINT + * the convenience definition of the parameters passed to the + * konforka::code_point constructor. + */ +#define CODEPOINT __FILE__,__PRETTY_FUNCTION__,__LINE__ +/** + * @def NOCODEPOINT + * the convenience definition for the codepoint denoting no particular point in + * code. + */ +#define NOCODEPOINT "no information" + +/** + * @brief The main konforka namespace. + */ +namespace konforka { + using std::string; + using std::list; + + /** + * @brief Pinpoint the code context. + * + * Class, holding the point in code, for instance, where the exception + * occured. + */ + class code_point { + public: + /** + * The string describing the point in code. + */ + string where; + /** + * The file (as provided by __FILE__) if available. + */ + string file; + /** + * The function name (as provided by __PRETTY_FUNCTION__) if + * available. + */ + string function; + /** + * The line number (as provided by __LINE__) if available. + */ + int line; + + /** + * Constructs the object, using only textual description of the + * point in code (no file, function, line information). + * @param w the description of the point in code. + */ + code_point(const string& w); + /** + * Constructs the object, specifying the exact position in code. + * @param fi source file name. + * @param fu function name. + * @param l the line number. + */ + code_point(const string& fi,const string& fu,int l); + + /** + * Extract the information on the point in code. + * @return the reference to the character string. + * @see where + */ + const char *c_str() const throw(); + + /** + * Build the textual description from the broken down information on + * the point in code. + * @see where + * @see file + * @see function + * @see line + */ + void make_where(); + }; + + /** + * @brief The basic exception class. + */ + class exception : public std::exception { + public: + /** + * The string, containing the description of exception. + */ + string _what; + /** + * Reference to the point in code where the exception has occured. + */ + code_point _where; + /** + * In case the exception has been rethrown a number of times, here + * we can trace where was it seen (a kind of backtrace). + */ + list<code_point> _seen; + + /** + * The simple constructor, only providing textual information on the + * exception nature and the point in code where the exception has + * occured. + * @param whe the point in code. + * @param wha the description of exception. + */ + exception(const string& whe, const string& wha); + /** + * The constructor, storing elaborate information on where the + * exception has occured. + * @param fi source file name. + * @param fu function name. + * @param l line number. + * @param w the error message. + * @see #CODEPOINT + */ + exception(const string& fi,const string& fu,int l,const string& w); + virtual ~exception() throw(); + + /** + * Extract the textual information on the point in code where + * exception has occured. + * @return the string describing point in code where exception has + * occured. + */ + virtual const char* where() const throw(); + /** + * Extract the textual information on the nature of the exception. + * @return the error message. + */ + virtual const char* what() const throw(); + + /** + * Register the point in code (described by the string) in the + * 'backtrace' list. + * @param w the description of the point in code. + */ + void see(const string& w); + /** + * Register the point in code in the 'backtrace' list. + * @param fi souce file name. + * @param fu function name. + * @param l line number. + * @see CODEPOINT + */ + void see(const string& fi,const string& fu,int l); + }; + + /** + * @brief errno-holding exception. + * + * The exception object storing the information provided by the errno + * variable. + */ + class system_error : public exception { + public: + /** + * The value of errno. + */ + int _errno; + + /** + * Construct the exception object storing plain text information on + * the point in code. + * @param whe the description of point in code. + * @param wha the error message. + */ + system_error(const string& whe,const string& wha); + /** + * Construct the exception object storing elaborate information on + * the point in code where it has occured. + * @param fi source file name. + * @param fu function name. + * @param l line number. + * @param w the error message. + * @see CODEPOINT + */ + system_error(const string& fi,const string& fu,int l,const string& w); + virtual ~system_error() throw(); + + /** + * Return the information on the system error recorded. + * @return the string describing the error occured. + */ + virtual const char* why() const throw(); + }; + +} + +#endif /* __KONFORKA_EXCEPTION_H */ +/* vim:set ft=cpp: */ diff --git a/include/konforka/pointer_map.h b/include/konforka/pointer_map.h new file mode 100644 index 0000000..d706e71 --- a/dev/null +++ b/include/konforka/pointer_map.h @@ -0,0 +1,105 @@ +#ifndef __KONFORKA_POINTER_MAP_H +#define __KONFORKA_POINTER_MAP_H + +#include <typeinfo> + +/** + * @file + * @brief mapping of pointers. + * + * The support for global mapping of pointers. Useful when using third-party + * libraries callbacks when the library does not provide mechanism for passing + * along custom context-dependent data. + */ + +namespace konforka { + + /** + * @brief internally used actual implementation of mapping pointer. + * + * @param tf the typeid of the key pointer. + * @param pf the key pointer. + * @param tt the typeid of the value pointer. + * @param pt the value pointer. + */ + void _map_pointer(const type_info& tf,void *pf,const type_info& tt,void *pt); + /** + * @brief internally used actual implementation of destroying mapped + * pointer. + * + * @param tf the typeid of the key pointer. + * @param pf the key pointer. + * @param tt the typeid of the value pointer. + * @param pt the value pointer. + */ + void _unmap_pointer(const type_info& tf,void *pf,const type_info& tt,void *pt); + /** + * @brief internally used actual implementation of retrieving mapped + * pointer. + * + * @param tf the typeid of the key pointer. + * @param pf the key pointer. + * @param tt the typeid of the value pointer. + * @return the value. + */ + void *_mapped_pointer(const type_info& tf,void *pf,const type_info& tt); + + /** + * @brief the object, maintaining mapped pointer. + * + * @param from_t the key type. + * @param to_t the value type. + */ + template<typename from_t,typename to_t> + class map_pointer { + public: + /** + * stored key. + */ + from_t _from; + /** + * stored value. + */ + to_t _to; + /** + * flag, specifying that the object is currently mapped. + */ + bool bmapped; + + /** + * @brief constructs the object, mapping the key/value pair. + * + * @param f the key. + * @param t the value. + */ + map_pointer(from_t f,to_t t) + : _from(f), _to(t), bmapped(false) { + _map_pointer(typeid(from_t),_from,typeid(to_t),_to); + bmapped=true; + } + /** + * @brief destructor unmaps the key/value pair stored. + */ + ~map_pointer() { + if(bmapped) + _unmap_pointer(typeid(from_t),_from,typeid(to_t),_to); + } + }; + + /** + * The template function for pointer retrieval. + * + * @param from_t the key type. + * @param to_t the value type. + * @param f the key. + * @return the value. + */ + template<typename from_t,typename to_t> + to_t mapped_pointer(from_t f) { + return (to_t)_mapped_pointer(typeid(from_t),f,typeid(to_t)); + } + +} + +#endif /* __KONFORKA_POINTER_MAP_H */ +/* vim:set ft=cpp: */ diff --git a/include/konforka/pqxx_pile.h b/include/konforka/pqxx_pile.h new file mode 100644 index 0000000..fdfaed6 --- a/dev/null +++ b/include/konforka/pqxx_pile.h @@ -0,0 +1,59 @@ +#ifndef __KONFORKA_PQXX_PILE_H +#define __KONFORKA_PQXX_PILE_H + +#include <pqxx/connection> +#include <konforka/resource_pile.h> + +/** + * @file + * @brief libpqxx-based postgresql connections pile. + */ + +namespace konforka { + + /** + * @brief the base for pqxx-based connection classes. + * + * @param pqxxc_t the type of libpqxx connection (pqxx::connection, + * pqxx::lazyconnection or pqxx::asyncconnection). + */ + template<typename pqxxc_t> + class pqxx_piled_connection_base : public resource_pile_base<string,pqxxc_t*, resource_pile_generic_ptr_factory<string,pqxxc_t> > { + public: + /** + * @brief the constractor based on connection info. + * + * @param ci connection info string. + */ + pqxx_piled_connection_base(const string& ci) + : resource_pile_base<string,pqxxc_t*, resource_pile_generic_ptr_factory<string,pqxxc_t> >(ci) { } + ~pqxx_piled_connection_base() { this->drop(); } + + /** + * @brief cast the object to the reference to the corresponding + * libpqxx type. + */ + operator pqxxc_t&(void) { return *this->get_content(); } + /** + * @brief cast the object to the const reference to the + * corresponding libpqxx type. + */ + operator const pqxxc_t&(void) const { return *this->get_content(); } + }; + + /** + * @brief the implementation for piling pqxx::connection objects. + */ + typedef pqxx_piled_connection_base<pqxx::connection> pqxx_piled_connection; + /** + * @brief the implementation for piling pqxx::lazyconnection objects. + */ + typedef pqxx_piled_connection_base<pqxx::lazyconnection> pqxx_piled_lazy_connection; + /** + * @brief the implementation for piling pqxx::asyncconnection objects. + */ + typedef pqxx_piled_connection_base<pqxx::asyncconnection> pqxx_piled_async_connection; +} + +#endif /* __KONFORKA_PQXX_PILE_H */ +/* vim:set ft=cpp: */ diff --git a/include/konforka/resource_pile.h b/include/konforka/resource_pile.h new file mode 100644 index 0000000..d76a07b --- a/dev/null +++ b/include/konforka/resource_pile.h @@ -0,0 +1,118 @@ +#ifndef __KONFORKA_RESOURCE_PILE_H +#define __KONFORKA_RESOURCE_PILE_H + +#include <map> +#include <konforka/responsible_wrapper.h> + +/** + * @file + * @brief resource-piling base support. + * + * Base for implementing resource-piling. + */ + +namespace konforka { + using std::multimap; + using std::pair; + + /** + * @brief template base class for resource piling. + * + * @param key_t the type used for keying resources. + * @param value_t the type of resource itself. + * @param factory_t the factory class, providing value_t allocate(key_t) + * static member. + */ + template<typename key_t,typename value_t,typename factory_t> + class resource_pile_base : public responsible_wrapper<value_t> { + /** + * @brief the type of the pile container itself. + */ + typedef multimap<key_t,value_t> pile_t; + /* + * @brief the pile of resources. + */ + static pile_t pile; + public: + /** + * @brief stored value for the key associated with the resource + * contained. + */ + key_t _key; + + /** + * @brief default constructor fetches or allocates resource. + * + * @param k the key for resource. + * @see allocate + */ + resource_pile_base(const key_t& k) { + allocate(k); + } + /** + * @brief destructor releases the resource back to pile. + */ + virtual ~resource_pile_base() { this->drop(); } + + /** + * @brief this is where the resource is handed back to pile. + */ + void release() { + pile.insert(pair<key_t,value_t>(_key,this->opkele)); + } + + /** + * @brief fetch from pile or allocate the resource. + * + * Try to see if we have a piled resource keyed to the argument. If + * we do -- fetch it from the pile, otherwise allocate anew. + * + * @param k the key for resource. + */ + void allocate(const key_t& k) { + this->drop(); + typename pile_t::iterator i = pile.find(k); + if(i==pile.end()) { + this->attach(factory_t::allocate(k)); + }else{ + this->attach(i->second); + try{ pile.erase(i); }catch(...){ _key = k; throw; } + } + _key = k; + } + + }; + + template<typename key_t,typename value_t,typename factory_t> + typename resource_pile_base<key_t,value_t,factory_t>::pile_t + resource_pile_base<key_t,value_t,factory_t>::pile; + + /** + * @brief the generic single parameter new-based resource factory. + * + * The generic resource factory using new as a way to allocate resource + * using the single-parameter constructor. + * + * @param key_t the key type. + * @param value_t the resource type. + * + * @see resource_pile_base + */ + template<typename key_t,typename value_t> + struct resource_pile_generic_ptr_factory { + public: + /** + * @brief allocate the resource using new. + * + * @param k the key. + * @return pointer to the newly allocated object. + */ + static value_t *allocate(const key_t& k) { + return new value_t(k); + } + }; + +} + +#endif /* __KONFORKA_RESOURCE_PILE_H */ +/* vim:set ft=cpp: */ diff --git a/include/konforka/responsible_wrapper.h b/include/konforka/responsible_wrapper.h new file mode 100644 index 0000000..374ad45 --- a/dev/null +++ b/include/konforka/responsible_wrapper.h @@ -0,0 +1,99 @@ +#ifndef __KONFORKA_RESPONSIBLE_WRAPPER_H +#define __KONFORKA_RESPONSIBLE_WRAPPER_H + +/** + * @file + * @brief The konforka::responsible_wrapper class declaration. + */ + +#include <konforka/basic_wrapper.h> + +namespace konforka { + + /** + * @brief The auto-cleanup wrapper class. + * + * The wrapper class that may feel responsible for releasing the resources + * associated with the content attached. + * + */ + template<typename T> + class responsible_wrapper : public basic_wrapper<T> { + public: + /** + * The type of wrapped content. + */ + typedef typename basic_wrapper<T>::content_type content_type; + /** + * Flag indicating whether the object feels responsible for + * releasing resources associated with the content. + */ + bool bresponsible; + + /** + * Default constructor creates the object with no content + * attached. + */ + responsible_wrapper() + : basic_wrapper<content_type>() { } + /** + * Constructor, associating the content with the instance. + * @param o the content. + * @param br indicates whether resources associated with the + * content should be released. + */ + responsible_wrapper(content_type o,bool br=true) + : basic_wrapper<content_type>(o), bresponsible(br) { } + /** + * Destructor releases resources associated with the content + * attached (if any), if the instance feels responsible for the + * content. + */ + virtual ~responsible_wrapper() { drop(); } + + /** + * Attaches the given content to the object. + * @param o the content. + * @param br indicates whether the object should feel + * responsible for releasing the content. + */ + void attach(content_type o,bool br=true) { + drop(); + basic_wrapper<content_type>::attach(o); + bresponsible = true; + } + + /** + * 'empties' object, releasing resources associated with the + * content if it feels responsible. + */ + virtual void drop() { + if(!this->is()) + return; + if(bresponsible) + release(); + this->bopkele = false; + } + + /** + * Detaches the content from the object without releasing + * resources even if feels responsible for it. + * @return the content attached. + */ + virtual content_type detach() { + this->ensure(); + this->bopkele = false; + return this->opkele; + } + + /** + * Pure virtual provided for derived classes to override for + * doing whatever it takes to release resources associated with + * the content. + */ + virtual void release() = 0; + }; +} + +#endif /* __KONFORKA_RESPONSIBLE_WRAPPER_H */ +/* vim:set ft=cpp: */ |