--- parser3/src/main/pa_pool.C 2001/10/02 17:05:49 1.29 +++ parser3/src/main/pa_pool.C 2026/04/25 13:38:46 1.69 @@ -1,123 +1,57 @@ /** @file Parser: pool class. - Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) - Author: Alexander Petrosyan (http://design.ru/paf) - - $Id: pa_pool.C,v 1.29 2001/10/02 17:05:49 parser Exp $ + Copyright (c) 2000-2026 Art. Lebedev Studio (https://www.artlebedev.com) + Authors: Konstantin Morshnev , Alexandr Petrosian */ #include "pa_pool.h" #include "pa_exception.h" #include "pa_common.h" +#include "pa_sapi.h" +#include "pa_charset.h" -#ifdef XML -#include -#include -#endif - -Pool::Pool(void *astorage) : - fstorage(astorage), fcontext(0), ftag(0), fexception(0) -#ifdef XML - , transcoder(0) -#endif - { -#ifdef XML - charset=new(*this) String(*this, "UTF-8"); -#else - charset=new(*this) String(*this, ""); -#endif -} +volatile const char * IDENT_PA_POOL_C="$Id: pa_pool.C,v 1.69 2026/04/25 13:38:46 moko Exp $" IDENT_PA_POOL_H; + +// Pool + +Pool::Pool(){} +static void cleanup(Pool::Cleanup item, int) { + if(item.cleanup) + item.cleanup(item.data); +} Pool::~Pool() { -#ifdef XML - delete transcoder; -#endif -} - -void Pool::fail_alloc(size_t size) const { - fexception->_throw(0, 0, - 0, - "failed to allocate %u bytes", size); -} - -void Pool::fail_register_cleanup() const { - fexception->_throw(0, 0, - 0, - "failed to register cleanup"); -} - -void Pool::set_charset(const String &new_charset) { - if(new_charset!=*charset) { -#ifdef XML - delete transcoder; transcoder=0; // flag "we need new transcoder" -#endif - charset=&new_charset; // for this charset - } -} - -#ifdef XML -void Pool::update_transcoder() { - if(transcoder) - return; - - XMLTransService::Codes resValue; - transcoder=XMLPlatformUtils::fgTransService->makeNewTranscoderFor(charset->cstr(), resValue, 60); - if(!transcoder) - THROW(0, 0, - charset, - "unsupported encoding"); -} - -const char *Pool::transcode_cstr(const XalanDOMString& s) { - update_transcoder(); - - const unsigned int len=s.size()*2; - XMLByte* dest=(XMLByte *)malloc((len+1)*sizeof(XMLByte)); - bool error=true; - try { - if(transcoder) { - unsigned int charsEaten; - unsigned int size=transcoder->transcodeTo( - s.c_str(), s.length(), - dest, len, - charsEaten, - XMLTranscoder::UnRep_RepChar //UnRep_Throw - ); - dest[size]=0; - error=false; - } - } catch(...) { - } - if(error) { - memset(dest, '?', s.size()); - ((char *)dest)[s.size()]=0; - } - return (const char *)dest; -} -String& Pool::transcode(const XalanDOMString& s) { - return *new(*this) String(*this, transcode_cstr(s)); -} - -void Pool::_throw(const String *source, const XSLException& e) { - if(e.getURI().empty()) - THROW(0, 0, - source, - "%s (%s)", - transcode_cstr(e.getMessage()), // message for exception - transcode_cstr(e.getType()) // type of exception - ); - else - THROW(0, 0, - source, - "%s (%s) %s(%d:%d)'", - transcode_cstr(e.getMessage()), // message for exception - transcode_cstr(e.getType()), // type of exception - - transcode_cstr(e.getURI()), // URI for the associated document, if any - e.getLineNumber(), // line number, or -1 if unknown - e.getColumnNumber() // column number, or -1 if unknown - ); + //__asm__("int3"); + //_asm int 3; + //fprintf(stderr, "cleanups: %d\n", cleanups.size()); + // cleanups first, because they use some object's memory pointers + cleanups.for_each(cleanup, 0); +} + +void Pool::register_cleanup(void (*cleanup) (void *), void *data) { + cleanups+=Cleanup(cleanup, data); +} + +static void unregister_cleanup(Pool::Cleanup& item, void* cleanup_data) { + if(item.data==cleanup_data) + item.cleanup=0; +} +void Pool::unregister_cleanup(void *cleanup_data) { + cleanups.for_each_ref(::unregister_cleanup, cleanup_data); +} + +// Pooled + +static void cleanup(void *data) { + static_cast(data)->~Pooled(); +} + +Pooled::Pooled(Pool& apool): fpool(apool) { + fpool.register_cleanup(cleanup, this); } -#endif +/// Sole: this got called automatically from Pool::~Pool() +Pooled::~Pooled() { + fpool.unregister_cleanup(this); +}