Annotation of parser3/src/include/pa_pool.h, revision 1.86.2.28
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.28! paf 12: static const char* IDENT_POOL_H="$Date: 2003/02/04 09:44:27 $";
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:
1.86.2.3 paf 224: template<typename T> class object_ptr {
1.86.2.1 paf 225: T *ptr;
226: public:
227: typedef T element_type;
1.86.2.2 paf 228:
1.86.2.3 paf 229: explicit object_ptr(T *ptr = 0) {
1.86.2.1 paf 230: this->ptr=ptr;
231: if(ptr)
1.86.2.2 paf 232: ptr->ref();
1.86.2.1 paf 233: }
1.86.2.21 paf 234: template<class B> object_ptr(const object_ptr<B>& src) {
235: this->ptr=src.get();
1.86.2.23 paf 236: if(ptr)
237: ptr->ref();
1.86.2.21 paf 238: }
1.86.2.3 paf 239: object_ptr(const object_ptr<T>& src) {
1.86.2.1 paf 240: ptr=src.get();
1.86.2.2 paf 241: ptr->ref();
1.86.2.1 paf 242: }
1.86.2.21 paf 243: object_ptr(T *ptr, int) {
244: this->ptr=ptr;
245: }
1.86.2.7 paf 246: object_ptr<T>& operator=(const object_ptr<T>& src) {
1.86.2.1 paf 247: if(this!=&src)
248: if(ptr!=src.get()) {
249: if(ptr)
1.86.2.2 paf 250: ptr->unref();
1.86.2.1 paf 251: ptr=src.get();
252: if(ptr)
1.86.2.2 paf 253: ptr->ref();
1.86.2.1 paf 254: }
1.86.2.6 paf 255: return *this;
1.86.2.1 paf 256: }
1.86.2.3 paf 257: ~object_ptr() {
1.86.2.1 paf 258: if(ptr)
1.86.2.2 paf 259: ptr->unref();
1.86.2.1 paf 260: }
261: T& operator*() const {
262: return *get();
263: }
264: T *operator->() const {
265: return get();
266: }
267: T *get() const {
268: return ptr;
1.86.2.7 paf 269: }
1.86.2.8 paf 270: operator bool() const {
1.86.2.7 paf 271: return get()!=0;
272: }
1.86.2.24 paf 273: bool operator !() const {
1.86.2.8 paf 274: return get()==0;
275: }
1.86.2.1 paf 276: };
1.86.2.2 paf 277:
1.86.2.16 paf 278: #define DECLARE_OBJECT_PTR(name) \
1.86.2.20 paf 279: typedef object_ptr<name> name##Ptr
1.86.2.18 paf 280:
281: // typedef object_ptr<name> name##Ptr; \
282: // const object_ptr<name> name##PtrZero(0);
1.86.2.8 paf 283:
1.86.2.24 paf 284: /// TEMPLATE CLASS smart_ptr, stolen from stl:auto_ptr & renamed field/params [not compiled on gcc]
1.86.2.2 paf 285: template<class T>
1.86.2.3 paf 286: class smart_ptr {
1.86.2.24 paf 287: bool owns;
288: T *ptr;
1.86.2.2 paf 289: public:
290: typedef T element_type;
1.86.2.24 paf 291: explicit smart_ptr(T *aptr = 0)
292: : owns(aptr != 0), ptr(aptr) {}
293: smart_ptr(const smart_ptr<T>& src)
294: : owns(src.owns), ptr(src.release()) {}
295: smart_ptr<T>& operator=(const smart_ptr<T>& src)
296: {if (this != &src)
1.86.2.25 paf 297: {if (ptr != src.get())
1.86.2.24 paf 298: {if (owns)
1.86.2.25 paf 299: delete ptr;
1.86.2.24 paf 300: owns = src.owns; }
301: else if (src.owns)
302: owns = true;
1.86.2.25 paf 303: ptr = src.release(); }
1.86.2.2 paf 304: return (*this); }
1.86.2.3 paf 305: ~smart_ptr()
1.86.2.24 paf 306: {if (owns)
1.86.2.25 paf 307: delete ptr; }
1.86.2.2 paf 308: T& operator*() const
309: {return (*get()); }
310: T *get() const
1.86.2.25 paf 311: {return ptr; }
1.86.2.2 paf 312: T *release() const
1.86.2.24 paf 313: {((smart_ptr<T> *)this)->owns = false;
1.86.2.25 paf 314: return (ptr); }
1.86.2.8 paf 315: operator bool() const {
1.86.2.10 paf 316: return get()!=0;
1.86.2.7 paf 317: }
1.86.2.9 paf 318: operator T*() const {
1.86.2.24 paf 319: return ptr;
1.86.2.9 paf 320: }
1.86.2.2 paf 321: };
322:
1.86.2.28! paf 323: // defines
! 324:
! 325: #define override
! 326: #define rethrow throw
! 327:
! 328: // memory
! 329:
! 330: inline void *operator new[] (size_t size) {
! 331: return pa_malloc(size);
! 332: }
! 333: inline void operator delete[] (void *ptr) {
! 334: pa_free(ptr);
! 335: }
! 336:
! 337: class PA_Allocated {
! 338: public:
! 339: /// the sole: instances allocated using our functions
! 340: static void *operator new(size_t size) {
! 341: return pa_malloc(size);
! 342: }
! 343: static void operator delete(void *ptr) {
! 344: pa_free(ptr);
! 345: }
! 346: static void *malloc(size_t size) {
! 347: return pa_malloc(size);
! 348: }
! 349: static void *calloc(size_t size) {
! 350: return pa_calloc(size);
! 351: }
! 352: static void *realloc(void *ptr, size_t size) {
! 353: return pa_realloc(ptr, size);
! 354: }
! 355:
! 356: };
! 357:
! 358: /**
! 359: Base for all Parser classes, memory allocation/dallocation goes via pa_malloc/pa_free.
! 360: */
! 361: class PA_Object: public PA_Allocated {
! 362: mutable unsigned long freferences;
! 363: public:
! 364: PA_Object(): freferences(0) {}
! 365: virtual ~PA_Object() {}
! 366:
! 367: void ref() const {
! 368: freferences++;
! 369: }
! 370: void unref() const {
! 371: if(freferences) {
! 372: if(--freferences==0)
! 373: delete this;
! 374: }
! 375: }
! 376: };
! 377: DECLARE_OBJECT_PTR(PA_Object);
! 378:
1.86.2.5 paf 379: // convinient types
380:
1.86.2.6 paf 381: typedef smart_ptr<char> CharPtr;
1.86.2.28! paf 382: //const CharPtr CharPtrZero(0);
1.1 paf 383:
384: #endif
E-mail: