Xerces C++でリソースの解放忘れをしないようにリソースの確保と解放を行うクラスを作りました。
エラーハンドリングはかなりいい加減なのでその辺は参考にしない方がいいかと思いますが、このようにメモリの明示的な解放が必要なモジュールをクラスでラップしておくと、うっかり解放忘れを防げるのでメモリリーク対策に有効です。
class XercesWapper
{
public:
enum Result{
XERCES_RESULT_SUCCESS,
XERCES_RESULT_NOT_INITIALIZED,
XERCES_RESULT_XML_ERROR,
XERCES_RESULT_DOM_ERROR,
XERCES_RESULT_NO_DOM_IMPLEMENTATION,
XERCES_RESULT_DOCUMENT_IS_NULL,
XERCES_RESULT_UNKNOWN_ERROR
};
public:
XercesWapper()
: xerces_initialized_(false)
, responsible_to_release_xdoc_(false)
, parser_(NULL)
, err_handler_(NULL)
, xdoc_(NULL)
, root_elem_(NULL)
, dom_impl_(NULL)
{
try
{
XMLPlatformUtils::Initialize();
}
catch(const XMLException& e)
{
char* message = XMLString::transcode(e.getMessage());
fprintf(stderr, "Error during initialization! : %s\n", message);
XMLString::release(&message);
return;
}
catch (...)
{
fprintf( stderr, "Unexpected Exception \n" );
return;
}
xerces_initialized_ = true;
dom_impl_ = DOMImplementationRegistry::getDOMImplementation(XMLString::transcode("Core"));
err_handler_ = (ErrorHandler*) new HandlerBase();
parser_ = new XercesDOMParser();
parser_->setErrorHandler(err_handler_);
}
~XercesWapper()
{
if( xerces_initialized_ )
{
if( xdoc_!=NULL&& responsible_to_release_xdoc_ )
{
xdoc_->release();
}
delete parser_;
delete err_handler_;
XMLPlatformUtils::Terminate();
}
}
bool xerces_initialized() const{ return xerces_initialized_; }
DOMDocument* xdoc(){ return xdoc_; }
DOMElement* root_elem(){ return root_elem_; }
DOMImplementation* dom_impl(){ return dom_impl_; }
XercesWapper::Result ParseXml( const char* xml_path )
{
if( xerces_initialized_==false ){ return XercesWrapper::XERCES_RESULT_NOT_INITIALIZED; }
try
{
parser_->parse(xml_path);
}
catch( const XMLException& e )
{
char* message = XMLString::transcode(e.getMessage());
fprintf( stderr, "Exception message is: %s\n", message );
XMLString::release(&message);
XMLPlatformUtils::Terminate();
return XercesWapper::XERCES_RESULT_XML_ERROR;
}
catch (const DOMException& e)
{
char* message = XMLString::transcode(e.msg);
fprintf( stderr, "Exception message is: %s\n", message );
XMLString::release(&message);
XMLPlatformUtils::Terminate();
return XercesWapper::XERCES_RESULT_DOM_ERROR;
}
catch (...)
{
fprintf( stderr, "Unexpected Exception \n" );
XMLPlatformUtils::Terminate();
return XercesWapper::XERCES_RESULT_UNKNOWN_ERROR;
}
xdoc_ = parser_->getDocument();
root_elem_ = xdoc_->getDocumentElement();
return XercesWapper::XERCES_RESULT_SUCCESS;
}
XercesWapper::Result CreateDocument( const char* root_name )
{
if( xerces_initialized_==false ){ return XercesWrapper::XERCES_RESULT_NOT_INITIALIZED; }
if( dom_impl_==NULL ){ return XercesWapper::XERCES_RESULT_NO_DOM_IMPLEMENTATION; }
xdoc_ = dom_impl_->createDocument(
0, // root element namespace URI.
XMLString::transcode(root_name), // root element name
0); // document type object (DTD).
root_elem_ = xdoc_->getDocumentElement();
responsible_to_release_xdoc_ = true;
return XercesWapper::XERCES_RESULT_SUCCESS;
}
XercesWapper::Result OutputDocument( const char* ouput_xml_path )
{
if( xerces_initialized_==false ){ return XercesWrapper::XERCES_RESULT_NOT_INITIALIZED; }
if( xdoc_==NULL ) { return XERCES_RESULT_DOCUMENT_IS_NULL; }
DOMImplementation *implementation = DOMImplementationRegistry::getDOMImplementation(L"LS");
DOMLSSerializer *serializer = ((DOMImplementationLS*)implementation)->createLSSerializer();
if (serializer->getDomConfig()->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true)){
serializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
}
serializer->setNewLine(XMLString::transcode("\r\n"));
XMLCh *tempFilePath = XMLString::transcode(ouput_xml_path);
XMLFormatTarget *formatTarget = new LocalFileFormatTarget(tempFilePath);
DOMLSOutput *output = ((DOMImplementationLS*)implementation)->createLSOutput();
output->setByteStream(formatTarget);
serializer->write(xdoc_, output);
serializer->release();
XMLString::release(&tempFilePath);
delete formatTarget;
output->release();
return XercesWapper::XERCES_RESULT_SUCCESS;
}
DOMElement* CreateElement( const char* elem_name )
{
if( xdoc_==NULL ) { return NULL; }
return xdoc_->createElement(XMLString::transcode(elem_name));
}
private:
XercesWrapper( const XercesWrapper &rhs );
XercesWrapper &operator=( const XercesWrapper &rhs );
private:
XercesDOMParser* parser_;
ErrorHandler* err_handler_;
DOMDocument* xdoc_;
DOMElement* root_elem_;
DOMImplementation* dom_impl_;
bool xerces_initialized_;
bool responsible_to_release_xdoc_;
};