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

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

E-mail: