ロゴ メインコンテンツへ
RSSフィード
「ソフトウェア開発」に関連する記事一覧

Xerces C++ メモリ解放忘れ防止用ラッパークラス

2013/02/11
(この記事の文字数: 157)

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_;
};

  このエントリーをはてなブックマークに追加  

<<「ソフトウェア開発」の記事一覧に戻る

<<「ソフトウェア開発」の次の記事

コメント(0 件)



コンテンツロード: 0.0084 sec
Copyright(C)2006-2024 puarts All Rights Reserved