1
0
mirror of https://github.com/cookiengineer/audacity synced 2026-02-10 05:30:01 +01:00
Files
audacity/src/xml/XMLFileReader.cpp
Paul Licameli 5e7d41ec07 Each .cpp/.mm file includes corresponding header before any other...
... except Audacity.h

This forces us to make each header contain all forward declarations or nested
headers that it requires, rather than depend on context.
2019-03-17 22:54:52 -04:00

132 lines
3.3 KiB
C++

/**********************************************************************
Audacity: A Digital Audio Editor
XMLFileReader.cpp
Dominic Mazzoni
*******************************************************************//**
\class XMLFileReader
\brief Reads a file and passes the results through an XMLTagHandler.
*//*******************************************************************/
#include "XMLFileReader.h"
#include <wx/defs.h>
#include <wx/ffile.h>
#include <wx/intl.h>
#include <string.h>
#include "../Internat.h"
XMLFileReader::XMLFileReader()
{
mParser = XML_ParserCreate(NULL);
XML_SetUserData(mParser, (void *)this);
XML_SetElementHandler(mParser, startElement, endElement);
XML_SetCharacterDataHandler(mParser, charHandler);
mBaseHandler = NULL;
mHandler.reserve(128);
}
XMLFileReader::~XMLFileReader()
{
XML_ParserFree(mParser);
}
bool XMLFileReader::Parse(XMLTagHandler *baseHandler,
const FilePath &fname)
{
wxFFile theXMLFile(fname, wxT("rb"));
if (!theXMLFile.IsOpened()) {
mErrorStr.Printf(_("Could not open file: \"%s\""), fname);
return false;
}
mBaseHandler = baseHandler;
const size_t bufferSize = 16384;
char buffer[16384];
int done = 0;
do {
size_t len = fread(buffer, 1, bufferSize, theXMLFile.fp());
done = (len < bufferSize);
if (!XML_Parse(mParser, buffer, len, done)) {
mErrorStr.Printf(_("Error: %hs at line %lu"),
XML_ErrorString(XML_GetErrorCode(mParser)),
(long unsigned int)XML_GetCurrentLineNumber(mParser));
theXMLFile.Close();
return false;
}
} while (!done);
theXMLFile.Close();
// Even though there were no parse errors, we only succeed if
// the first-level handler actually got called, and didn't
// return false.
if (mBaseHandler)
return true;
else {
mErrorStr.Printf(_("Could not load file: \"%s\""), fname);
return false;
}
}
wxString XMLFileReader::GetErrorStr()
{
return mErrorStr;
}
// static
void XMLFileReader::startElement(void *userData, const char *name,
const char **atts)
{
XMLFileReader *This = (XMLFileReader *)userData;
Handlers &handlers = This->mHandler;
if (handlers.empty()) {
handlers.push_back(This->mBaseHandler);
}
else {
if (XMLTagHandler *const handler = handlers.back())
handlers.push_back(handler->ReadXMLChild(name));
else
handlers.push_back(NULL);
}
if (XMLTagHandler *& handler = handlers.back()) {
if (!handler->ReadXMLTag(name, atts)) {
handler = nullptr;
if (handlers.size() == 1)
This->mBaseHandler = nullptr;
}
}
}
// static
void XMLFileReader::endElement(void *userData, const char *name)
{
XMLFileReader *This = (XMLFileReader *)userData;
Handlers &handlers = This->mHandler;
if (XMLTagHandler *const handler = handlers.back())
handler->ReadXMLEndTag(name);
handlers.pop_back();
}
// static
void XMLFileReader::charHandler(void *userData, const char *s, int len)
{
XMLFileReader *This = (XMLFileReader *)userData;
Handlers &handlers = This->mHandler;
if (XMLTagHandler *const handler = handlers.back())
handler->ReadXMLContent(s, len);
}