--- parser3/src/include/pa_pool.h 2003/01/27 15:07:47 1.86.2.9 +++ parser3/src/include/pa_pool.h 2017/11/15 22:48:57 1.93 @@ -1,7 +1,7 @@ /** @file - Parser: Parser: reference counting classes decls. + Parser: pool class decl. - Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2000-2017 Art. Lebedev Studio (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ @@ -9,354 +9,75 @@ #ifndef PA_POOL_H #define PA_POOL_H -static const char* IDENT_POOL_H="$Date: 2003/01/27 15:07:47 $"; +#define IDENT_PA_POOL_H "$Id: pa_pool.h,v 1.93 2017/11/15 22:48:57 moko Exp $" #include "pa_config_includes.h" +#include "pa_array.h" -#ifdef XML -# include "gdome.h" -// for xmlChar -# include "libxml/tree.h" -#endif - -void *pa_malloc(size_t size); -void *pa_calloc(size_t size); -void pa_free(void *ptr); -void *pa_realloc(void *ptr, size_t size); - -// forwards - -class Exception; -class String; -class Charset; -class GdomeDOMString_auto_ptr; - -/* * - Pool mechanizm allows users not to free up allocated memory, +/** + Pool mechanizm allows users not to free up allocated objects, leaving that problem to 'pools'. @see Pooled -* / +*/ -class Pool { +class Pool : public PA_Allocated { public: - Pool(void *astorage); + struct Cleanup : public PA_Allocated { + void (*cleanup) (void *); + void *data; - //{@ statistics - size_t total_allocated() { return ftotal_allocated; } - unsigned int total_times() { return ftotal_times; } - //}@ - - void set_context(void *acontext) { fcontext=acontext; } - void *get_context() { return fcontext; } - - /// allocates some bytes on pool - void *malloc(size_t size, int place=0) { - return check(real_malloc(size, place), size); - } - /// allocates some bytes clearing them with zeros - void *calloc(size_t size) { - return check(real_calloc(size), size); - } + Cleanup(void (*acleanup) (void *), void *adata): cleanup(acleanup), data(adata) {} + }; - /// registers a routine to clean up non-pooled allocations - void register_cleanup(void (*cleanup) (void *), void *data) { - if(!real_register_cleanup(cleanup, data)) - fail_register_cleanup(); - } - - //{@ helpers - void *copy(const void *buf, const size_t size); - char *copy(const char *cstr); - //}@ - - //{@ source charset - void set_source_charset(Charset& acharset); - Charset& get_source_charset(); - //}@ - - //{@ client charset - void set_client_charset(Charset& charset); - Charset& get_client_charset(); - //}@ - -#ifdef XML - - /// @see Charset::transcode_cstr(xmlChar *s); - const char *transcode_cstr(xmlChar *s); - /// @see Charset::transcode(xmlChar *s); - String& transcode(xmlChar *s -#ifndef NO_STRING_ORIGIN - , const String *origin -#endif - ); - /// @see Charset::transcode_cstr(GdomeDOMString *s); - const char *transcode_cstr(GdomeDOMString *s); - /// @see Charset::transcode(GdomeDOMString *s); - String& transcode(GdomeDOMString *s -#ifndef NO_STRING_ORIGIN - , const String *origin -#endif - ); - /// @see Charset::transcode_cstr(const char *buf, size_t buf_size=0); - xmlChar *transcode_buf2xchar(const char *buf, size_t buf_size=0); - /// @see Charset::transcode(const String& s) - GdomeDOMString_auto_ptr transcode(const String& s); + Pool(); + ~Pool(); -#endif + /// registers a routine to clean up non-pooled allocations + void register_cleanup(void (*cleanup) (void *), void *data); + /// unregister it, looking it up by it's data + void unregister_cleanup(void *cleanup_data); private: - void *fstorage; - void *fcontext; - Charset *source_charset; - Charset *client_charset; + Array cleanups; private: //{ /// @name implementation defined - void *real_malloc(size_t size, int place); - void *real_calloc(size_t size); bool real_register_cleanup(void (*cleanup) (void *), void *data); //} private: - /// checks whether mem allocated OK. throws exception otherwise - void *check(void *ptr, size_t size) { - if(ptr) { - ftotal_allocated+=size; - ftotal_times++; - return ptr; - } - - fail_alloc(size); - - // never reached - return 0; - } - /// throws allocation exception - void fail_alloc(size_t size) const; - /// throws register cleanup exception void fail_register_cleanup() const; -private: // statistics - - size_t ftotal_allocated; - unsigned int ftotal_times; - private: //disabled Pool(const Pool&); Pool& operator= (const Pool&); }; -*/ - /** Base for all classes that are allocated in 'pools'. - - Holds Pool object. Contains useful wrappers to it's methods. - - @see NEW -* / - -// all classes that are members parents of packed class [String] -// sould be packed also to avoid sparc odd st/lduh problem -#include "pa_pragma_pack_begin.h" -class Pooled { + Holds Pool object. +*/ +class Pooled : public PA_Allocated { // the pool i'm allocated on - Pool *fpool; + Pool& fpool; public: - /// the Pooled-sole: Pooled instances can be allocated in Pool rather then on heap - static void *operator new(size_t size, Pool& apool) { - return apool.malloc(size, 1); - } - - Pooled(Pool& apool) : fpool(&apool) {} + Pooled(Pool& apool); /// my pool - Pool& pool() const { return *fpool; } - - /** used for moving objects from one pool to another. - in between object can have no pool and can not be used - @see SQL_Driver_manager - * / - void set_pool(Pool *apool) { fpool=apool; } + //Pool& pool() const { return *fpool; } - //{ - /// @name useful wrapper around pool - void *malloc(size_t size, int place=0) const { return fpool->malloc(size, place); } - void *calloc(size_t size) const { return fpool->calloc(size); } - void register_cleanup(void (*cleanup) (void *), void *data) { fpool->register_cleanup(cleanup, data); } - void *copy(const void *buf, const size_t size) { return fpool->copy(buf, size); } - char *copy(const char *cstr) { return fpool->copy(cstr); } -#ifdef XML - - const char *transcode_cstr(GdomeDOMString *s) { return fpool->transcode_cstr(s); } - String& transcode(GdomeDOMString *s -#ifndef NO_STRING_ORIGIN - , const String *origin -#endif - ) { - return fpool->transcode(s -#ifndef NO_STRING_ORIGIN - , origin -#endif - ); - } + /// Sole: this got called automatically from Pool::~Pool() + virtual ~Pooled(); -#endif - //} -}; -#include "pa_pragma_pack_end.h" -/// useful macro for creating objects on current Pooled object Pooled::pool() -#define NEW new(pool()) -*/ - -#define override - -void *operator new(size_t size) { - return pa_malloc(size); -} -void operator delete(void *ptr) { - pa_free(ptr); -} - -class PA_Allocated { -public: - /// the sole: instances allocated using our functions - static void *operator new(size_t size) { - return pa_malloc(size); - } - static void operator delete(void *ptr) { - pa_free(ptr); - } -}; - -/** - Base for all Parser classes, memory allocation/dallocation goes via pa_malloc/pa_free. -*/ -class PA_Object: public PA_Allocated { - mutable unsigned long references; -public: - PA_Object(): references(0) {} - virtual ~PA_Object()=0; - - void ref() const { - references++; - } - void unref() const { - if(references) { - if(--references==0) - delete this; - } - } }; - -template class object_ptr { - T *ptr; -public: - typedef T element_type; - - explicit object_ptr(T *ptr = 0) { - this->ptr=ptr; - if(ptr) - ptr->ref(); - } - object_ptr(const object_ptr& src) { - ptr=src.get(); - ptr->ref(); - } - object_ptr& operator=(const object_ptr& src) { - if(this!=&src) - if(ptr!=src.get()) { - if(ptr) - ptr->unref(); - ptr=src.get(); - if(ptr) - ptr->ref(); - } - return *this; - } - ~object_ptr() { - if(ptr) - ptr->unref(); - } - T& operator*() const { - return *get(); - } - T *operator->() const { - return get(); - } - T *get() const { - return ptr; - } - // so one could assign object_ptr to object_ptr - operator object_ptr() const{ - return *this; - } - operator bool() const { - return get()!=0; - } - operator !() const { - return get()==0; - } -}; - -#define DECLARE_OBJECT_PTR(name) typedef object_ptr name##Ptr; - -/// TEMPLATE CLASS smart_ptr, stolen from stl:auto_ptr -template - class smart_ptr { -public: - typedef T element_type; - explicit smart_ptr(T *_P = 0) - : _Owns(_P != 0), _Ptr(_P) {} - smart_ptr(const smart_ptr& _Y) - : _Owns(_Y._Owns), _Ptr(_Y.release()) {} - smart_ptr& operator=(const smart_ptr& _Y) - {if (this != &_Y) - {if (_Ptr != _Y.get()) - {if (_Owns) - delete _Ptr; - _Owns = _Y._Owns; } - else if (_Y._Owns) - _Owns = true; - _Ptr = _Y.release(); } - return (*this); } - ~smart_ptr() - {if (_Owns) - delete _Ptr; } - T& operator*() const - {return (*get()); } - T *get() const - {return (_Ptr); } - T *release() const - {((smart_ptr *)this)->_Owns = false; - return (_Ptr); } - // so one could assign smart_ptr to smart_ptr - operator smart_ptr() const { - return *this; - } - operator bool() const { - return get(); - } - operator T*() const { - return _Ptr; - } -private: - bool _Owns; - T *_Ptr; - }; - -// convinient types - -typedef smart_ptr CharPtr; - #endif