|
|
| version 1.52, 2001/05/17 10:22:24 | version 1.67, 2001/10/19 15:34:39 |
|---|---|
| Line 13 | Line 13 |
| #include "pa_config_includes.h" | #include "pa_config_includes.h" |
| #ifdef XML | |
| #include <memory> | |
| #include <XalanDOM/XalanDOMString.hpp> | |
| #include <util/TransService.hpp> | |
| #endif | |
| // forwards | |
| class Exception; | class Exception; |
| class Temp_exception; | class Temp_exception; |
| class String; | |
| /** | /** |
| Pool mechanizm allows users not to free up allocated memory, | Pool mechanizm allows users not to free up allocated memory, |
| leaving that problem to 'pools'. | leaving that problem to 'pools'. |
| Also holds Exception object, which can be temporary set using | |
| Temp_exception auto-object. | |
| @see Pooled | @see Pooled |
| */ | */ |
| class Pool { | class Pool { |
| friend Temp_exception; | |
| public: | public: |
| Pool(void *astorage) : fstorage(astorage), fcontext(0), ftag(0), fexception(0) {} | Pool(void *astorage); |
| ~Pool(); | |
| void set_context(void *acontext) { fcontext=acontext; } | void set_context(void *acontext) { fcontext=acontext; } |
| void *context() { return fcontext; } | void *get_context() { return fcontext; } |
| void set_tag(void *atag) { ftag=atag; } | void set_tag(void *atag) { ftag=atag; } |
| void *tag() { return ftag; } | void *tag() { return ftag; } |
| /// current exception object of the pool | |
| Exception& exception() const { return *fexception; } | |
| /// allocates some bytes on pool | /// allocates some bytes on pool |
| void *malloc(size_t size/*, int place=0*/) { | void *malloc(size_t size/*, int place=0*/) { |
| return check(real_malloc(size/*, place*/), size); | return check(real_malloc(size/*, place*/), size); |
| Line 50 public: | Line 53 public: |
| return check(real_calloc(size), size); | return check(real_calloc(size), size); |
| } | } |
| /// 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(); | |
| } | |
| /// resets transcoder if they change charset | |
| void set_charset(const String &charset); | |
| /// returns current charset | |
| const String& get_charset() { return *charset; } | |
| private: | private: |
| void *fstorage; | void *fstorage; |
| void *fcontext; | void *fcontext; |
| void *ftag; | void *ftag; |
| const String *charset; | |
| private: | private: |
| Line 62 private: | Line 77 private: |
| /// @name implementation defined | /// @name implementation defined |
| void *real_malloc(size_t size/*, int place*/); | void *real_malloc(size_t size/*, int place*/); |
| void *real_calloc(size_t size); | void *real_calloc(size_t size); |
| bool real_register_cleanup(void (*cleanup) (void *), void *data); | |
| //} | //} |
| private: | private: |
| Line 71 private: | Line 87 private: |
| if(ptr) | if(ptr) |
| return ptr; | return ptr; |
| fail(size); | fail_alloc(size); |
| // never reached | // never reached |
| return 0; | return 0; |
| } | } |
| /// throws proper exception | /// throws allocation exception |
| void fail(size_t size) const; | void fail_alloc(size_t size) const; |
| private: // exception handling | /// throws register cleanup exception |
| void fail_register_cleanup() const; | |
| // exception replacement mechanism is 'private'zed from direct usage | #ifdef XML |
| // Temp_exception object enforces paired set/restore | |
| Exception *set_exception(Exception *e){ | public: |
| Exception *r=fexception; | /// converts Xalan string to char * |
| fexception=e; | const char *transcode_cstr(const XalanDOMString& s); |
| return r; | /// converts Xalan string to parser String |
| } | String& transcode(const XalanDOMString& s); |
| void restore_exception(Exception *e) { | /// converts char * to Xalan string |
| fexception=e; | std::auto_ptr<XalanDOMString> transcode_buf(const char *buf, size_t buf_size); |
| } | /// converts parser String to Xalan string |
| std::auto_ptr<XalanDOMString> transcode(const String& s); | |
| private: | |
| void set_charset(const char *new_scharset); | |
| void update_transcoder(); | |
| private: | private: |
| // current request's exception object | XMLTranscoder *transcoder; |
| Exception *fexception; | |
| #endif | |
| private: //disabled | private: //disabled |
| // Pool(const Pool&) {} | Pool(const Pool&); |
| Pool& operator = (const Pool&) { return *this; } | Pool& operator= (const Pool&); |
| }; | }; |
| /** | /** |
| Line 108 private: //disabled | Line 132 private: //disabled |
| Holds Pool object. Contains useful wrappers to it's methods. | Holds Pool object. Contains useful wrappers to it's methods. |
| @see NEW, Temp_exception | @see NEW |
| */ | */ |
| class Pooled { | class Pooled { |
| // the pool i'm allocated on | // the pool i'm allocated on |
| Line 131 public: | Line 155 public: |
| */ | */ |
| void set_pool(Pool *apool) { fpool=apool; } | void set_pool(Pool *apool) { fpool=apool; } |
| /// useful wrapper around pool | //{ |
| /// @name useful wrapper around pool | |
| void *malloc(size_t size) const { return fpool->malloc(size); } | void *malloc(size_t size) const { return fpool->malloc(size); } |
| /// useful wrapper around pool | |
| void *calloc(size_t size) const { return fpool->calloc(size); } | void *calloc(size_t size) const { return fpool->calloc(size); } |
| /// useful wrapper around pool | void register_cleanup(void (*cleanup) (void *), void *data) { fpool->register_cleanup(cleanup, data); } |
| Exception& exception() const { return fpool->exception(); } | #ifdef XML |
| const char *transcode_cstr(const XalanDOMString& s) { return fpool->transcode_cstr(s); } | |
| String& transcode(const XalanDOMString& s) { return fpool->transcode(s); } | |
| #endif | |
| //} | |
| }; | }; |
| /// useful macro for creating objects on current Pooled object Pooled::pool() | /// useful macro for creating objects on current Pooled object Pooled::pool() |
| #define NEW new(pool()) | #define NEW new(pool()) |
| /** | |
| Auto-object used for temporary changing Pool's exception(). | |
| Use by with these macros: | |
| @code | |
| TRY { | |
| // ... | |
| if(?) | |
| THROW(?); | |
| // ... | |
| } CATCH(e) { | |
| // code, using e fields | |
| // e.comment() | |
| } | |
| END_CATCH | |
| @endcode | |
| @see TRY, THROW | |
| */ | |
| class Temp_exception { | |
| Pool& fpool; | |
| Exception *saved_exception; | |
| public: | |
| Temp_exception(Pool& apool, Exception& exception) : | |
| fpool(apool), | |
| saved_exception(apool.set_exception(&exception)) { | |
| } | |
| ~Temp_exception() { | |
| fpool.restore_exception(saved_exception); | |
| } | |
| }; | |
| #define XTRY(pool) \ | |
| { \ | |
| Exception temp_exception; \ | |
| Temp_exception le(pool, temp_exception); \ | |
| if(setjmp(temp_exception.mark)==0) | |
| #define XTHROW(exception) exception._throw | |
| #define XCATCH(e) \ | |
| else{ \ | |
| Exception& e=temp_exception; | |
| #define XEND_CATCH \ | |
| } \ | |
| } | |
| //@{ | |
| /// @see Temp_exception | |
| #define TRY XTRY(pool()) | |
| #define THROW XTHROW(exception()) | |
| #define CATCH(e) XCATCH(e) | |
| #define END_CATCH XEND_CATCH | |
| #define PTRY XTRY(pool) | |
| #define PTHROW XTHROW(pool.exception()) | |
| #define PCATCH(e) XCATCH(e) | |
| #define PEND_CATCH XEND_CATCH | |
| //@} | |
| #endif | #endif |