[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xerces-c-users
Subject:    Re: MemBufFormatTarget possible bug
From:       John Snelson <john.snelson () oracle ! com>
Date:       2008-04-11 11:42:37
Message-ID: 47FF4EAD.1040704 () oracle ! com
[Download RAW message or body]

Hi Affe,

Alberto is right about the use of these classes. Janitor is a Xerces-C 
class, where as AutoDelete is an XQilla class. The AutoDelete class is 
more flexible than the Janitor class, which is why XQilla defines it's 
own version.

John

Alberto Massari wrote:
> wernwa@gmx.de wrote:
>> hi Alberto
>>
>> indeed, now it is ok. thank you, i have not much experience with Janitor.
>>
>> I have another question about Janitor or AutoDelete Template Classes, 
>> because i saw them in many examples. What are the big difference 
>> between them and when should i use these classes.
>>
>>   
> 
> A Janitor or a AutoDelete object is used as a stack variable when you 
> want to delete an object allocated in the heap as soon as it goes out of 
> scope (because of normal execution flow, or because of an exception).
> That is,
> 
>  try
>  {
>    Janitor<Type> j(new Type(...));
>    ...
>  }
>  catch(....) {}
> 
> is the same of
> 
>  Type* p=new Type(..);
>  try
>  {
>    ...
>  }
>  catch(...) {}
>  delete p;
> 
> Alberto
> 
> 
>> greetings
>>    Affe
>>
>>
>> -------- Original-Nachricht --------
>>  
>>> Datum: Fri, 11 Apr 2008 10:13:58 +0200
>>> Von: Alberto Massari <amassari@datadirect.com>
>>> An: c-users@xerces.apache.org
>>> Betreff: Re: MemBufFormatTarget possible bug
>>>     
>>
>>  
>>> Affe,
>>> the memory becomes corrupted because you create the 
>>> MemBufFormatTarget using the memory manager belonging to the 
>>> DynamicContext stored in the dynamic_context Janitor variable; but 
>>> once that you exit from the try/catch block, the context is deleted, 
>>> the memory it allocated is deleted, and the storage used by the 
>>> MemBufFormatTarget is gone (it can still contain the original data, 
>>> or just pieces of it, but it could also trigger access violations).
>>> You should move the code that copies the result of the query into the 
>>> std::string inside the try/catch block, or move the dynamic_context 
>>> out of it.
>>>
>>> Alberto
>>>
>>> wernwa@gmx.de wrote:
>>>    
>>>> hi Alberto
>>>>
>>>> can you please try my example again, now i have a complete copy&paste
>>>>       
>>> programm, maybe i do some wrong initializing. thanks
>>>    
>>>> my output is always (the first character should be '<b b':
>>>>
>>>> length :70
>>>> 1n="b1">      some b1 text</b>
>>>> <b b2n="b2">      some b2 text</b>
>>>>
>>>>
>>>>
>>>>
>>>> #include <iostream>
>>>> #include <vector>
>>>> #include <map>
>>>>
>>>> #include <xercesc/framework/StdOutFormatTarget.hpp>
>>>> #include <xercesc/framework/LocalFileFormatTarget.hpp>
>>>> #include <xercesc/util/XMLUri.hpp>
>>>> #include <xercesc/parsers/XercesDOMParser.hpp>
>>>> #include <xercesc/framework/MemBufInputSource.hpp>
>>>> #include <xercesc/util/OutOfMemoryException.hpp>
>>>> #include <xercesc/framework/MemBufFormatTarget.hpp>
>>>>
>>>> //XQilla includes
>>>> #include <xqilla/xqilla-simple.hpp>
>>>> #include <xqilla/ast/LocationInfo.hpp>
>>>> #include <xqilla/context/MessageListener.hpp>
>>>> #include <xqilla/utils/PrintAST.hpp>
>>>> #include <xqilla/events/EventSerializer.hpp>
>>>> #include <xqilla/events/NSFixupFilter.hpp>
>>>> #include <xqilla/xerces/XercesConfiguration.hpp>
>>>> #include <xqilla/fastxdm/FastXDMConfiguration.hpp>
>>>> #include <xqilla/utils/XQillaPlatformUtils.hpp>
>>>>
>>>> #if defined(XERCES_HAS_CPP_NAMESPACE)
>>>> XERCES_CPP_NAMESPACE_USE
>>>> #endif
>>>>
>>>> using namespace std;
>>>>
>>>> #define QUERY_BUFFER_SIZE 32 * 1024
>>>> #define BASEURI_BUFFER_SIZE 2 * 1024
>>>>
>>>>
>>>> int main(int argc, char *argv[])
>>>> {
>>>>       XMLPlatformUtils::Initialize();
>>>>     XQillaPlatformUtils::initialize();
>>>>
>>>>
>>>>     XercesDOMParser *parser = new XercesDOMParser();
>>>>     parser->setValidationScheme(XercesDOMParser::Val_Auto);
>>>>     parser->setDoNamespaces(true);
>>>>     parser->setDoSchema(false);
>>>>     parser->setValidationSchemaFullChecking(false);
>>>>     parser->setCreateEntityReferenceNodes(false);
>>>>
>>>>
>>>>         std::string xml("\
>>>> <test>\
>>>>       <b b1n='b1'> some b1 text\
>>>>     </b>\
>>>>     <b b2n='b2'>some b2 text\
>>>>     </b>\
>>>>     <a url='test.xml' name='aaaa'/>\
>>>> </test>\
>>>> ");
>>>>
>>>>  MemBufInputSource*memBufIS = new MemBufInputSource
>>>>  (
>>>>         (const XMLByte*)xml.c_str()
>>>>         , xml.length()
>>>>         , "somedoc"
>>>>         , false
>>>>  );
>>>>
>>>>
>>>>  try
>>>>     {
>>>>         parser->parse(*memBufIS);
>>>>     }
>>>>     catch (const OutOfMemoryException&)
>>>>     {
>>>>         cout<<"OutOfMemoryException"<<endl;
>>>>     }
>>>>     catch (const XMLException& e)
>>>>     {
>>>>         cout << "XMLException" << endl;
>>>>     }
>>>>         catch (...)
>>>>     {
>>>>         cout << "some unnown exception" << endl;
>>>>     }
>>>>     DOMNode*root = parser->getDocument()->getFirstChild();
>>>>     ((DOMDocument*)parser->getDocument())->setDocumentURI(0);
>>>>
>>>>
>>>>     XercesConfiguration xercesConf;
>>>>     XQillaConfiguration *conf = &xercesConf;
>>>>     XQilla xqilla;
>>>>     int language = XQilla::XQUERY;
>>>>     language |= XQilla::UPDATE;
>>>>      Janitor<DynamicContext> contextGuard
>>>>         (xqilla.createContext((XQilla::Language)language, conf));
>>>>     DynamicContext *context = contextGuard.get();
>>>>
>>>>     context->setXPath1CompatibilityMode(false);      
>>>> MemBufFormatTarget*memtarget=0;
>>>>
>>>>
>>>> try{
>>>>     XQQuery *query = xqilla.parse(
>>>>
>>>>         //query 1  (only corrupt when mem=1024)
>>>>         //X("declare revalidation skip;/test/b")
>>>>
>>>>                 //query 2 (always corrupt)
>>>>         X("for $i in (1 to 2)\
>>>> return\
>>>> <b>\
>>>> {attribute {concat('b', $i, 'n')} {concat('b',$i)}}\
>>>>       some b{$i} text\
>>>> </b>")
>>>>
>>>>         ,contextGuard.release()
>>>>             );
>>>>     Janitor<DynamicContext>
>>>>       
>>> dynamic_context(query->createDynamicContext());
>>>    
>>>>     Node::Ptr node = xercesConf.createNode(root,dynamic_context.get());
>>>>     dynamic_context->setContextItem(node.get());
>>>>     dynamic_context->setContextPosition(1);
>>>>     dynamic_context->setContextSize(1);
>>>>
>>>>
>>>>     int mem=0;
>>>>     //int mem=1024;
>>>>    memtarget = new MemBufFormatTarget(mem,
>>>>                       dynamic_context->getMemoryManager());
>>>>    EventSerializer writer("UTF-8", "1.1", memtarget,              
>>>> dynamic_context->getMemoryManager());
>>>>    writer.addNewlines(true);
>>>>    NSFixupFilter nsfilter(&writer, 
>>>> dynamic_context->getMemoryManager());
>>>>    query->execute(&nsfilter, dynamic_context.get());
>>>>    }
>>>>   catch(XQException &e) {}
>>>>
>>>>     int count = memtarget->getLen()*sizeof(XMLByte);
>>>>     string result((char*)memtarget->getRawBuffer(),
>>>>                     count);
>>>>     cout << "length :" << count << endl;
>>>>         cout <<  result << endl;
>>>>
>>>>     XMLPlatformUtils::Terminate();
>>>>     XQillaPlatformUtils::terminate();
>>>> return 0;
>>>> }
>>>>
>>>>
>>>> greetings
>>>>    Affe
>>>>         
>>
>>   
> 
> 


-- 
John Snelson, Oracle Corporation            http://snelson.org.uk/john
Berkeley DB XML:            http://oracle.com/database/berkeley-db/xml
XQilla:                                  http://xqilla.sourceforge.net
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic