Use memory rather than temporary files to pass XML content

This commit is contained in:
Zane U. Ji 2013-12-16 11:45:20 +08:00
parent b03707961c
commit d7bd982545
3 changed files with 72 additions and 92 deletions

View File

@ -526,72 +526,68 @@ bool WrapLibxml::bufferWellFormed ( const std::string& buffer )
} }
int WrapLibxml::saveEncoding ( int WrapLibxml::saveEncoding (
const std::string& buffer, const std::string &utf8Buffer,
const std::string& fileName, const wxString &fileNameSource,
const std::string& encoding ) const wxString &fileNameDestination,
wxMemoryBuffer *outputBuffer,
const wxString &encoding )
{ {
xmlParserCtxtPtr ctxt = xmlNewParserCtxt(); return saveEncoding ( utf8Buffer.c_str(), utf8Buffer.length(),
if ( !ctxt ) fileNameSource, fileNameDestination, outputBuffer, encoding );
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;
} }
int WrapLibxml::saveEncodingFromFile ( int WrapLibxml::saveEncoding (
const std::string& fileNameSource, const wxString &fileNameSource,
const std::string& fileNameDestination, const wxString &fileNameDestination,
const std::string& encoding ) 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(); xmlParserCtxtPtr ctxt = xmlNewParserCtxt();
if ( !ctxt ) if ( !ctxt )
return -1; return -1;
xmlSubstituteEntitiesDefault ( 0 ); xmlDocPtr docPtr;
xmlKeepBlanksDefault ( 1 ); // prevents single-line output 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 )
xmlDocPtr docPtr = xmlCtxtReadFile ( flags |= XML_PARSE_NONET;
ctxt, if ( utf8Buffer != NULL )
fileNameSource.c_str(), docPtr = xmlCtxtReadMemory ( ctxt, utf8Buffer, utf8BufferSize,
NULL, CONV ( fileNameSource ), "UTF-8", flags );
( 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 else
docPtr = xmlCtxtReadFile ( ctxt, fileNameSource.c_str(), NULL, flags );
if ( !docPtr ) if ( !docPtr )
{ {
xmlFreeParserCtxt ( ctxt ); xmlFreeParserCtxt ( ctxt );
return -1; return -1;
} }
int result = xmlSaveFileEnc ( int result;
fileNameDestination.c_str(), if ( outputBuffer == NULL )
{
result = xmlSaveFileEnc (
CONV ( fileNameDestination ),
docPtr, docPtr,
encoding.c_str() ); encoding.utf8_str() );
}
// ensure entity warnings are treated as errors! else
if ( !getLastError().empty() ) {
result = -1; xmlChar *buffer;
xmlDocDumpMemoryEnc ( docPtr, &buffer, &result,
encoding.utf8_str() );
outputBuffer->AppendData ( buffer, result );
xmlFree ( buffer );
}
xmlFreeDoc ( docPtr ); xmlFreeDoc ( docPtr );
xmlFreeParserCtxt ( ctxt ); xmlFreeParserCtxt ( ctxt );

View File

@ -82,13 +82,22 @@ class WrapLibxml
std::pair<int, int> getErrorPosition(); std::pair<int, int> getErrorPosition();
std::string getOutput(); std::string getOutput();
int saveEncoding ( int saveEncoding (
const std::string& buffer, const std::string &utf8Buffer,
const std::string& fileName, const wxString &fileNameSource,
const std::string& encoding ); const wxString &fileNameDestination,
int saveEncodingFromFile ( wxMemoryBuffer *outputBuffer, /* Override fileNameDestination*/
const std::string& fileNameSource, const wxString &encoding );
const std::string& fileNameDestination, int saveEncoding (
const std::string& encoding ); 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 ( wxString catalogResolve (
const wxString &publicId, const wxString &publicId,
const wxString &systemId ); const wxString &systemId );

View File

@ -4280,24 +4280,11 @@ void MyFrame::OnEncoding ( wxCommandEvent& event )
if ( scd.ShowModal() == wxID_CANCEL ) if ( scd.ShowModal() == wxID_CANCEL )
return; 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<WrapLibxml> wl ( new WrapLibxml ( libxmlNetAccess ) );
int res; int res;
wxMemoryBuffer output;
WrapTempFileName sourceFileName ( doc->getFullFileName() ); std::auto_ptr<WrapLibxml> wl ( new WrapLibxml ( libxmlNetAccess ) );
saveRawUtf8 ( sourceFileName.name(), bufferUtf8 ); res = wl->saveEncoding ( doc->myGetTextRaw(), doc->getFullFileName(),
wxEmptyString, &output, scd.GetStringSelection() );
res = wl->saveEncodingFromFile ( sourceFileName.name(), tempFileName.name(), selectionUtf8 );
if ( res == -1 ) if ( res == -1 )
{ {
wxString wideError = wl->getLastError(); wxString wideError = wl->getLastError();
@ -4306,20 +4293,11 @@ void MyFrame::OnEncoding ( wxCommandEvent& event )
return; 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<XmlUtf8Reader> xur ( new XmlUtf8Reader ( std::auto_ptr<XmlUtf8Reader> xur ( new XmlUtf8Reader (
false, false,
expandInternalEntities, expandInternalEntities,
newBuffer.size() ) ); output.GetDataLen() ) );
if ( !xur->parse ( newBuffer ) ) if ( !xur->parse ( ( const char * ) output.GetData(), output.GetDataLen() ) )
{ {
messagePane ( _ ( "Cannot set encoding (cannot parse temporary file)" ), messagePane ( _ ( "Cannot set encoding (cannot parse temporary file)" ),
CONST_STOP ); CONST_STOP );
@ -4783,12 +4761,9 @@ bool MyFrame::saveFile ( XmlDoc *doc, wxString& fileName, bool checkLastModified
} }
else // all other encodings handled by Libxml else // all other encodings handled by Libxml
{ {
XmlEncodingHandler::setUtf8 ( utf8Buffer );
auto_ptr<WrapLibxml> wl ( new WrapLibxml ( libxmlNetAccess ) ); auto_ptr<WrapLibxml> wl ( new WrapLibxml ( libxmlNetAccess ) );
int result = wl->saveEncoding ( utf8Buffer,
WrapTempFileName sourceFileName ( fileName ); doc->getFullFileName(), fileName, NULL, encoding );
saveRawUtf8 ( sourceFileName.name(), utf8Buffer );
int result = wl->saveEncodingFromFile ( sourceFileName.name(), fileNameLocal, encoding );
if ( result == -1 ) if ( result == -1 )
{ {
success = saveRawUtf8 ( fileNameLocal, utf8Buffer, false, isXml ); success = saveRawUtf8 ( fileNameLocal, utf8Buffer, false, isXml );