Annotation of parser3/src/include/pa_pool.h, revision 1.86.2.8

1.34      paf         1: /** @file
1.86.2.1  paf         2:        Parser: Parser: reference counting classes decls.
1.36      paf         3: 
1.86      paf         4:        Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com)
1.36      paf         5: 
1.78      paf         6:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1       paf         7: */
                      8: 
                      9: #ifndef PA_POOL_H
                     10: #define PA_POOL_H
1.82      paf        11: 
1.86.2.8! paf        12: static const char* IDENT_POOL_H="$Date: 2003/01/24 11:33:02 $";
1.1       paf        13: 
1.52      parser     14: #include "pa_config_includes.h"
1.1       paf        15: 
1.59      parser     16: #ifdef XML
1.75      paf        17: #      include "gdome.h"
1.76      paf        18: // for xmlChar
                     19: #      include "libxml/tree.h"
1.59      parser     20: #endif
1.55      parser     21: 
1.86.2.1  paf        22: void *pa_malloc(size_t size);
                     23: void *pa_calloc(size_t size);
                     24: void pa_free(void *ptr);
                     25: void *pa_realloc(void *ptr, size_t size);
                     26: 
1.55      parser     27: // forwards
                     28: 
1.21      paf        29: class Exception;
1.55      parser     30: class String;
1.73      paf        31: class Charset;
1.75      paf        32: class GdomeDOMString_auto_ptr;
1.55      parser     33: 
1.86.2.1  paf        34: /* * 
1.34      paf        35:        Pool mechanizm allows users not to free up allocated memory,
                     36:        leaving that problem to 'pools'.
                     37: 
1.38      paf        38:        @see Pooled
1.86.2.1  paf        39: * /
1.47      paf        40: 
1.1       paf        41: class Pool {
                     42: public:
1.18      paf        43: 
1.55      parser     44:        Pool(void *astorage);
1.18      paf        45: 
1.79      paf        46:        //{@ statistics
1.70      paf        47:        size_t total_allocated() { return ftotal_allocated; }
                     48:        unsigned int total_times() { return ftotal_times; }
1.79      paf        49:        //}@
1.70      paf        50: 
1.40      paf        51:        void set_context(void *acontext) { fcontext=acontext; }
1.64      parser     52:        void *get_context() { return fcontext; }
1.39      paf        53: 
1.34      paf        54:        /// allocates some bytes on pool
1.68      paf        55:        void *malloc(size_t size, int place=0) {
                     56:                return check(real_malloc(size, place), size);
1.18      paf        57:        }
1.34      paf        58:        /// allocates some bytes clearing them with zeros
1.18      paf        59:        void *calloc(size_t size) {
                     60:                return check(real_calloc(size), size);
                     61:        }
1.39      paf        62: 
1.53      parser     63:        /// registers a routine to clean up non-pooled allocations
1.54      parser     64:        void register_cleanup(void (*cleanup) (void *), void *data) {
                     65:                if(!real_register_cleanup(cleanup, data))
                     66:                        fail_register_cleanup();
                     67:        }
1.53      parser     68: 
1.84      paf        69:        //{@ helpers
                     70:        void *copy(const void *buf, const size_t size);
                     71:        char *copy(const char *cstr);
                     72:        //}@
                     73: 
1.79      paf        74:        //{@ source charset
1.73      paf        75:        void set_source_charset(Charset& acharset);
                     76:        Charset& get_source_charset();
1.79      paf        77:        //}@
1.73      paf        78: 
1.79      paf        79:        //{@ client charset
1.73      paf        80:        void set_client_charset(Charset& charset);
                     81:        Charset& get_client_charset();
1.79      paf        82:        //}@
1.73      paf        83: 
                     84: #ifdef XML
1.74      paf        85: 
1.76      paf        86:        /// @see Charset::transcode_cstr(xmlChar *s);
                     87:        const char *transcode_cstr(xmlChar *s);
                     88:        /// @see Charset::transcode(xmlChar *s);
1.85      paf        89:        String& transcode(xmlChar *s
                     90: #ifndef NO_STRING_ORIGIN
                     91:                , const String *origin
                     92: #endif
                     93:                );
1.76      paf        94:        /// @see Charset::transcode_cstr(GdomeDOMString *s);
1.74      paf        95:        const char *transcode_cstr(GdomeDOMString *s);
1.76      paf        96:        /// @see Charset::transcode(GdomeDOMString *s);
1.85      paf        97:        String& transcode(GdomeDOMString *s
                     98: #ifndef NO_STRING_ORIGIN
                     99:                , const String *origin
                    100: #endif
                    101:                );
1.81      paf       102:        /// @see Charset::transcode_cstr(const char *buf, size_t buf_size=0);
                    103:        xmlChar *transcode_buf2xchar(const char *buf, size_t buf_size=0);
1.73      paf       104:        /// @see Charset::transcode(const String& s)
1.75      paf       105:        GdomeDOMString_auto_ptr transcode(const String& s);
1.74      paf       106: 
1.73      paf       107: #endif
1.60      parser    108: 
1.39      paf       109: private:
                    110: 
                    111:        void *fstorage;
1.40      paf       112:        void *fcontext;
1.73      paf       113:        Charset *source_charset;
                    114:        Charset *client_charset;
1.8       paf       115: 
1.50      parser    116: private: 
                    117:        
                    118:        //{
                    119:        /// @name implementation defined
1.68      paf       120:     void *real_malloc(size_t size, int place);
1.20      paf       121:     void *real_calloc(size_t size);
1.54      parser    122:        bool real_register_cleanup(void (*cleanup) (void *), void *data);
1.50      parser    123:        //}
1.17      paf       124: 
1.23      paf       125: private: 
1.17      paf       126: 
1.34      paf       127:        /// checks whether mem allocated OK. throws exception otherwise
1.23      paf       128:        void *check(void *ptr, size_t size) {
1.70      paf       129:                if(ptr) {
                    130:                        ftotal_allocated+=size;
                    131:                        ftotal_times++;
1.23      paf       132:                        return ptr;
1.70      paf       133:                }
1.23      paf       134: 
1.54      parser    135:                fail_alloc(size);
1.23      paf       136: 
                    137:                // never reached
                    138:                return 0;
                    139:        }
1.54      parser    140:        /// throws allocation exception
                    141:        void fail_alloc(size_t size) const;
                    142: 
                    143:        /// throws register cleanup exception
                    144:        void fail_register_cleanup() const;
1.70      paf       145: 
                    146: private: // statistics
                    147:        
                    148:        size_t ftotal_allocated;
                    149:        unsigned int ftotal_times;
1.59      parser    150: 
1.8       paf       151: private: //disabled
                    152: 
1.64      parser    153:        Pool(const Pool&);
                    154:        Pool& operator= (const Pool&);
1.21      paf       155: };
1.86.2.1  paf       156: */
                    157: 
1.21      paf       158: 
1.35      paf       159: /** 
1.34      paf       160:        Base for all classes that are allocated in 'pools'.
                    161: 
                    162:        Holds Pool object. Contains useful wrappers to it's methods.
1.38      paf       163: 
1.64      parser    164:        @see NEW
1.86.2.1  paf       165: * /
1.80      paf       166: 
                    167: // all classes that are members parents of packed class [String] 
                    168: // sould be packed also to avoid sparc odd st/lduh problem
                    169: #include "pa_pragma_pack_begin.h"
1.21      paf       170: class Pooled {
1.23      paf       171:        // the pool i'm allocated on
1.49      paf       172:        Pool *fpool;
1.21      paf       173: public:
1.37      paf       174: 
                    175:        /// the Pooled-sole: Pooled instances can be allocated in Pool rather then on heap
1.21      paf       176:        static void *operator new(size_t size, Pool& apool) { 
1.68      paf       177:                return apool.malloc(size, 1);
1.21      paf       178:        }
                    179: 
1.49      paf       180:        Pooled(Pool& apool) : fpool(&apool) {}
1.23      paf       181: 
1.34      paf       182:        /// my pool
1.49      paf       183:        Pool& pool() const { return *fpool; }
                    184: 
                    185:        /** used for moving objects from one pool to another. 
                    186:                in between object can have no pool and can not be used
                    187:                @see SQL_Driver_manager
1.86.2.1  paf       188:        * /
1.49      paf       189:        void set_pool(Pool *apool) { fpool=apool; }
1.21      paf       190: 
1.57      parser    191:        //{
                    192:        /// @name useful wrapper around pool
1.68      paf       193:        void *malloc(size_t size, int place=0) const { return fpool->malloc(size, place); }
1.49      paf       194:        void *calloc(size_t size) const { return fpool->calloc(size); }
1.57      parser    195:        void register_cleanup(void (*cleanup) (void *), void *data) { fpool->register_cleanup(cleanup, data); }
1.84      paf       196:        void *copy(const void *buf, const size_t size) { return fpool->copy(buf, size); }
                    197:        char *copy(const char *cstr) { return fpool->copy(cstr); }
1.59      parser    198: #ifdef XML
1.74      paf       199: 
                    200:        const char *transcode_cstr(GdomeDOMString *s) { return fpool->transcode_cstr(s); }
1.85      paf       201:        String& transcode(GdomeDOMString *s
                    202: #ifndef NO_STRING_ORIGIN
                    203:                , const String *origin
                    204: #endif
                    205:                ) { 
                    206:                return fpool->transcode(s
                    207: #ifndef NO_STRING_ORIGIN
                    208:                        , origin
                    209: #endif         
                    210:                        ); 
                    211:        }
1.74      paf       212: 
1.59      parser    213: #endif
1.57      parser    214:        //}
1.23      paf       215: };
1.80      paf       216: #include "pa_pragma_pack_end.h"
1.34      paf       217: /// useful macro for creating objects on current Pooled object Pooled::pool()
1.23      paf       218: #define NEW new(pool())
1.86.2.1  paf       219: */
                    220: 
1.86.2.2  paf       221: #define override
                    222: 
                    223: void *operator new(size_t size) { 
                    224:        return pa_malloc(size);
                    225: }
                    226: void operator delete(void *ptr) {
                    227:        pa_free(ptr);
                    228: }
1.86.2.1  paf       229: 
1.86.2.2  paf       230: class PA_Allocated {
1.86.2.1  paf       231: public:
1.86.2.2  paf       232:        /// the sole: instances allocated using our functions
1.86.2.1  paf       233:        static void *operator new(size_t size) { 
                    234:                return pa_malloc(size);
                    235:        }
                    236:        static void operator delete(void *ptr) {
                    237:                pa_free(ptr);
                    238:        }
                    239: };
                    240: 
1.86.2.2  paf       241: /** 
                    242:        Base for all Parser classes, memory allocation/dallocation goes via pa_malloc/pa_free.
                    243: */
                    244: class PA_Object: public PA_Allocated {
                    245:        mutable unsigned long references;
                    246: public:
                    247:        PA_Object(): references(0) {}
                    248:        virtual ~PA_Object()=0;
                    249:         
1.86.2.4  paf       250:        void ref() const {
1.86.2.2  paf       251:                references++;
                    252:        }
1.86.2.4  paf       253:        void unref() const {
1.86.2.2  paf       254:                if(references) {
                    255:                        if(--references==0)
                    256:                                delete this;
                    257:                }
                    258:        }
                    259: };
                    260: 
                    261: 
1.86.2.3  paf       262: template<typename T> class object_ptr {
1.86.2.1  paf       263:        T *ptr;
                    264: public:
                    265:        typedef T element_type;
1.86.2.2  paf       266: 
1.86.2.3  paf       267:        explicit object_ptr(T *ptr = 0) {
1.86.2.1  paf       268:                this->ptr=ptr;
                    269:                if(ptr)
1.86.2.2  paf       270:                        ptr->ref();
1.86.2.1  paf       271:        }
1.86.2.3  paf       272:        object_ptr(const object_ptr<T>& src) {
1.86.2.1  paf       273:                ptr=src.get();
1.86.2.2  paf       274:                ptr->ref();
1.86.2.1  paf       275:        }
1.86.2.7  paf       276:    object_ptr<T>& operator=(const object_ptr<T>& src) {
1.86.2.1  paf       277:                if(this!=&src)
                    278:                        if(ptr!=src.get()) {
                    279:                                if(ptr)
1.86.2.2  paf       280:                                        ptr->unref();
1.86.2.1  paf       281:                                ptr=src.get();
                    282:                                if(ptr)
1.86.2.2  paf       283:                                        ptr->ref();
1.86.2.1  paf       284:                        }
1.86.2.6  paf       285:                return *this;
1.86.2.1  paf       286:        }
1.86.2.3  paf       287:     ~object_ptr() {
1.86.2.1  paf       288:                if(ptr)
1.86.2.2  paf       289:                        ptr->unref();
1.86.2.1  paf       290:        }
                    291:     T& operator*() const {
                    292:                return *get();
                    293:        }
                    294:     T *operator->() const {
                    295:                return get();
                    296:        }
                    297:     T *get() const {
                    298:                return ptr;
                    299:        }
1.86.2.7  paf       300:        // so one could assign object_ptr<const T> to object_ptr<T>
1.86.2.8! paf       301:        operator object_ptr<const T>() const{
1.86.2.7  paf       302:                return *this;
                    303:        }
1.86.2.8! paf       304:        operator bool() const {
1.86.2.7  paf       305:                return get()!=0;
                    306:        }
1.86.2.8! paf       307:        operator !() const {
        !           308:                return get()==0;
        !           309:        }
1.86.2.1  paf       310: };
1.86.2.2  paf       311: 
1.86.2.8! paf       312: #define DECLARE_OBJECT_PTR(name) typedef object_ptr<name> name##Ptr;
        !           313: 
1.86.2.3  paf       314: /// TEMPLATE CLASS smart_ptr, stolen from stl:auto_ptr
1.86.2.2  paf       315: template<class T>
1.86.2.3  paf       316:        class smart_ptr {
1.86.2.2  paf       317: public:
                    318:        typedef T element_type;
1.86.2.3  paf       319:        explicit smart_ptr(T *_P = 0)
1.86.2.2  paf       320:                : _Owns(_P != 0), _Ptr(_P) {}
1.86.2.3  paf       321:        smart_ptr(const smart_ptr<T>& _Y)
1.86.2.2  paf       322:                : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
1.86.2.3  paf       323:        smart_ptr<T>& operator=(const smart_ptr<T>& _Y)
1.86.2.2  paf       324:                {if (this != &_Y)
                    325:                        {if (_Ptr != _Y.get())
                    326:                                {if (_Owns)
                    327:                                        delete _Ptr;
                    328:                                _Owns = _Y._Owns; }
                    329:                        else if (_Y._Owns)
                    330:                                _Owns = true;
                    331:                        _Ptr = _Y.release(); }
                    332:                return (*this); }
1.86.2.3  paf       333:        ~smart_ptr()
1.86.2.2  paf       334:                {if (_Owns)
                    335:                        delete _Ptr; }
                    336:        T& operator*() const
                    337:                {return (*get()); }
                    338:        T *get() const
                    339:                {return (_Ptr); }
                    340:        T *release() const
1.86.2.3  paf       341:                {((smart_ptr<T> *)this)->_Owns = false;
1.86.2.2  paf       342:                return (_Ptr); }
1.86.2.8! paf       343:        // so one could assign smart_ptr<const T> to smart_ptr<T>
        !           344:        operator smart_ptr<const T>() const {
        !           345:                return *this;
        !           346:        }
        !           347:        operator bool() const {
1.86.2.7  paf       348:                return get();
                    349:        }
1.86.2.2  paf       350: private:
                    351:        bool _Owns;
                    352:        T *_Ptr;
                    353:        };
                    354: 
1.86.2.5  paf       355: // convinient types
                    356: 
1.86.2.6  paf       357: typedef smart_ptr<char> CharPtr;
1.86.2.8! paf       358: typedef smart_ptr<const char> ConstCharPtr;
1.1       paf       359: 
                    360: #endif

E-mail: