From d7bd982545425a92dfc3908a9535dc9bd401836c Mon Sep 17 00:00:00 2001 From: "Zane U. Ji" Date: Mon, 16 Dec 2013 11:45:20 +0800 Subject: [PATCH] Use memory rather than temporary files to pass XML content --- src/wraplibxml.cpp | 100 ++++++++++++++++++++---------------------- src/wraplibxml.h | 23 +++++++--- src/xmlcopyeditor.cpp | 41 ++++------------- 3 files changed, 72 insertions(+), 92 deletions(-) diff --git a/src/wraplibxml.cpp b/src/wraplibxml.cpp index e098515..19d0101 100644 --- a/src/wraplibxml.cpp +++ b/src/wraplibxml.cpp @@ -526,72 +526,68 @@ bool WrapLibxml::bufferWellFormed ( const std::string& buffer ) } int WrapLibxml::saveEncoding ( - const std::string& buffer, - const std::string& fileName, - const std::string& encoding ) + const std::string &utf8Buffer, + const wxString &fileNameSource, + const wxString &fileNameDestination, + wxMemoryBuffer *outputBuffer, + const wxString &encoding ) { - xmlParserCtxtPtr ctxt = xmlNewParserCtxt(); - if ( !ctxt ) - return -1; - - xmlSubstituteEntitiesDefault ( 0 ); - - xmlKeepBlanksDefault ( 1 ); // prevents single-line output - - xmlDocPtr docPtr = xmlCtxtReadMemory ( - ctxt, - buffer.c_str(), - buffer.size(), - "", - NULL, - XML_PARSE_DTDLOAD | XML_PARSE_DTDVALID | XML_PARSE_PEDANTIC//XML_PARSE_NONET//XML_PARSE_DTDLOAD//0//(netAccess) ? XML_PARSE_DTDLOAD | XML_PARSE_NOENT : XML_PARSE_DTDLOAD | XML_PARSE_NONET | XML_PARSE_NOENT//0 - ); - if ( !docPtr ) - { - xmlFreeParserCtxt ( ctxt ); - return -1; - } - - int result = xmlSaveFileEnc ( - fileName.c_str(), - docPtr, - encoding.c_str() ); - xmlFreeDoc ( docPtr ); - xmlFreeParserCtxt ( ctxt ); - return result; + return saveEncoding ( utf8Buffer.c_str(), utf8Buffer.length(), + fileNameSource, fileNameDestination, outputBuffer, encoding ); } -int WrapLibxml::saveEncodingFromFile ( - const std::string& fileNameSource, - const std::string& fileNameDestination, - const std::string& encoding ) +int WrapLibxml::saveEncoding ( + const wxString &fileNameSource, + const wxString &fileNameDestination, + const wxString &encoding ) +{ + return saveEncoding ( NULL, 0, fileNameSource, fileNameDestination, + NULL, encoding ); +} + +int WrapLibxml::saveEncoding ( + const char *utf8Buffer, + size_t utf8BufferSize, + const wxString &fileNameSource, + const wxString &fileNameDestination, + wxMemoryBuffer *outputBuffer, + const wxString &encoding ) { xmlParserCtxtPtr ctxt = xmlNewParserCtxt(); if ( !ctxt ) return -1; - xmlSubstituteEntitiesDefault ( 0 ); - xmlKeepBlanksDefault ( 1 ); // prevents single-line output - - xmlDocPtr docPtr = xmlCtxtReadFile ( - ctxt, - fileNameSource.c_str(), - NULL, - ( netAccess ) ? XML_PARSE_DTDLOAD : XML_PARSE_DTDLOAD | XML_PARSE_NONET );//XML_PARSE_NONET//XML_PARSE_DTDLOAD//0//(netAccess) ? XML_PARSE_DTDLOAD | XML_PARSE_NOENT : XML_PARSE_DTDLOAD | XML_PARSE_NONET | XML_PARSE_NOENT//0 + xmlDocPtr docPtr; + int flags = XML_PARSE_DTDLOAD | XML_PARSE_PEDANTIC /*| XML_PARSE_DTDVALID*/;//XML_PARSE_NONET//XML_PARSE_DTDLOAD//0//(netAccess) ? XML_PARSE_DTDLOAD | XML_PARSE_NOENT : XML_PARSE_DTDLOAD | XML_PARSE_NONET | XML_PARSE_NOENT//0 + if ( !netAccess ) + flags |= XML_PARSE_NONET; + if ( utf8Buffer != NULL ) + docPtr = xmlCtxtReadMemory ( ctxt, utf8Buffer, utf8BufferSize, + CONV ( fileNameSource ), "UTF-8", flags ); + else + docPtr = xmlCtxtReadFile ( ctxt, fileNameSource.c_str(), NULL, flags ); if ( !docPtr ) { xmlFreeParserCtxt ( ctxt ); return -1; } - int result = xmlSaveFileEnc ( - fileNameDestination.c_str(), - docPtr, - encoding.c_str() ); - - // ensure entity warnings are treated as errors! - if ( !getLastError().empty() ) - result = -1; + int result; + if ( outputBuffer == NULL ) + { + result = xmlSaveFileEnc ( + CONV ( fileNameDestination ), + docPtr, + encoding.utf8_str() ); + } + else + { + xmlChar *buffer; + xmlDocDumpMemoryEnc ( docPtr, &buffer, &result, + encoding.utf8_str() ); + outputBuffer->AppendData ( buffer, result ); + xmlFree ( buffer ); + } xmlFreeDoc ( docPtr ); xmlFreeParserCtxt ( ctxt ); diff --git a/src/wraplibxml.h b/src/wraplibxml.h index cb48993..bae1368 100644 --- a/src/wraplibxml.h +++ b/src/wraplibxml.h @@ -82,13 +82,22 @@ class WrapLibxml std::pair getErrorPosition(); std::string getOutput(); int saveEncoding ( - const std::string& buffer, - const std::string& fileName, - const std::string& encoding ); - int saveEncodingFromFile ( - const std::string& fileNameSource, - const std::string& fileNameDestination, - const std::string& encoding ); + const std::string &utf8Buffer, + const wxString &fileNameSource, + const wxString &fileNameDestination, + wxMemoryBuffer *outputBuffer, /* Override fileNameDestination*/ + const wxString &encoding ); + int saveEncoding ( + const wxString &fileNameSource, + const wxString &fileNameDestination, + const wxString &encoding ); + int saveEncoding ( + const char *utf8Buffer, + size_t utf8BufferSize, + const wxString &fileNameSource, + const wxString &fileNameDestination, + wxMemoryBuffer *outputBuffer, /* Override fileNameDestination*/ + const wxString &encoding ); wxString catalogResolve ( const wxString &publicId, const wxString &systemId ); diff --git a/src/xmlcopyeditor.cpp b/src/xmlcopyeditor.cpp index aadb073..39d4b57 100644 --- a/src/xmlcopyeditor.cpp +++ b/src/xmlcopyeditor.cpp @@ -4280,24 +4280,11 @@ void MyFrame::OnEncoding ( wxCommandEvent& event ) if ( scd.ShowModal() == wxID_CANCEL ) return; - wxString selection; - std::string selectionUtf8, bufferUtf8; - - selection = scd.GetStringSelection(); - selectionUtf8 = selection.mb_str ( wxConvUTF8 ); - - getRawText ( doc, bufferUtf8 ); - XmlEncodingHandler::setUtf8 ( bufferUtf8, true ); - - WrapTempFileName tempFileName ( _T ( "" ) ); - - std::auto_ptr wl ( new WrapLibxml ( libxmlNetAccess ) ); int res; - - WrapTempFileName sourceFileName ( doc->getFullFileName() ); - saveRawUtf8 ( sourceFileName.name(), bufferUtf8 ); - - res = wl->saveEncodingFromFile ( sourceFileName.name(), tempFileName.name(), selectionUtf8 ); + wxMemoryBuffer output; + std::auto_ptr wl ( new WrapLibxml ( libxmlNetAccess ) ); + res = wl->saveEncoding ( doc->myGetTextRaw(), doc->getFullFileName(), + wxEmptyString, &output, scd.GetStringSelection() ); if ( res == -1 ) { wxString wideError = wl->getLastError(); @@ -4306,20 +4293,11 @@ void MyFrame::OnEncoding ( wxCommandEvent& event ) return; } - std::string newBuffer; - bool success = ReadFile::run ( tempFileName.name(), newBuffer ); - if ( !success ) - { - messagePane ( _ ( "Cannot set encoding (cannot open temporary file)" ), - CONST_STOP ); - return; - } - std::auto_ptr xur ( new XmlUtf8Reader ( false, expandInternalEntities, - newBuffer.size() ) ); - if ( !xur->parse ( newBuffer ) ) + output.GetDataLen() ) ); + if ( !xur->parse ( ( const char * ) output.GetData(), output.GetDataLen() ) ) { messagePane ( _ ( "Cannot set encoding (cannot parse temporary file)" ), CONST_STOP ); @@ -4783,12 +4761,9 @@ bool MyFrame::saveFile ( XmlDoc *doc, wxString& fileName, bool checkLastModified } else // all other encodings handled by Libxml { - XmlEncodingHandler::setUtf8 ( utf8Buffer ); auto_ptr wl ( new WrapLibxml ( libxmlNetAccess ) ); - - WrapTempFileName sourceFileName ( fileName ); - saveRawUtf8 ( sourceFileName.name(), utf8Buffer ); - int result = wl->saveEncodingFromFile ( sourceFileName.name(), fileNameLocal, encoding ); + int result = wl->saveEncoding ( utf8Buffer, + doc->getFullFileName(), fileName, NULL, encoding ); if ( result == -1 ) { success = saveRawUtf8 ( fileNameLocal, utf8Buffer, false, isXml );