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