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:
[EMAIL PROTECTED] 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 <[EMAIL PROTECTED]>
An: [email protected]
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
[EMAIL PROTECTED] 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