mirror of
https://github.com/cookiengineer/audacity
synced 2026-02-17 08:17:59 +01:00
Locate and position the current Audacity source code, and clear a variety of old junk out of the way into junk-branches
This commit is contained in:
369
src/xml/XMLWriter.cpp
Normal file
369
src/xml/XMLWriter.cpp
Normal file
@@ -0,0 +1,369 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
XMLWriter.cpp
|
||||
|
||||
Leland Lucius
|
||||
|
||||
*******************************************************************//**
|
||||
|
||||
\class XMLWriter
|
||||
\brief Base class for XMLFileWriter and XMLStringWriter that provides
|
||||
the general functionality for creating XML in UTF8 encoding.
|
||||
|
||||
*//****************************************************************//**
|
||||
|
||||
\class XMLFileWriter
|
||||
\brief Wrapper to output XML data to files.
|
||||
|
||||
*//****************************************************************//**
|
||||
|
||||
\class XMLStringWriter
|
||||
\brief Wrapper to output XML data to strings.
|
||||
|
||||
*//*******************************************************************/
|
||||
|
||||
#include <wx/defs.h>
|
||||
#include <wx/ffile.h>
|
||||
#include <wx/intl.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../Internat.h"
|
||||
#include "XMLWriter.h"
|
||||
#include "XMLTagHandler.h"
|
||||
|
||||
///
|
||||
/// XMLWriter base class
|
||||
///
|
||||
XMLWriter::XMLWriter()
|
||||
{
|
||||
mDepth = 0;
|
||||
mInTag = false;
|
||||
mHasKids.Add(false);
|
||||
}
|
||||
|
||||
XMLWriter::~XMLWriter()
|
||||
{
|
||||
}
|
||||
|
||||
void XMLWriter::StartTag(const wxString &name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (mInTag) {
|
||||
Write(wxT(">\n"));
|
||||
mInTag = false;
|
||||
}
|
||||
|
||||
for (i = 0; i < mDepth; i++) {
|
||||
Write(wxT("\t"));
|
||||
}
|
||||
|
||||
Write(wxString::Format(wxT("<%s"), name.c_str()));
|
||||
|
||||
mTagstack.Insert(name, 0);
|
||||
mHasKids[0] = true;
|
||||
mHasKids.Insert(false, 0);
|
||||
mDepth++;
|
||||
mInTag = true;
|
||||
}
|
||||
|
||||
void XMLWriter::EndTag(const wxString &name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (mTagstack.GetCount() > 0) {
|
||||
if (mTagstack[0] == name) {
|
||||
if (mHasKids[1]) { // There will always be at least 2 at this point
|
||||
if (mInTag) {
|
||||
Write(wxT("/>\n"));
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < mDepth - 1; i++) {
|
||||
Write(wxT("\t"));
|
||||
}
|
||||
Write(wxString::Format(wxT("</%s>\n"), name.c_str()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write(wxT(">\n"));
|
||||
}
|
||||
mTagstack.RemoveAt(0);
|
||||
mHasKids.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
mDepth--;
|
||||
mInTag = false;
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxString &name, const wxString &value)
|
||||
{
|
||||
Write(wxString::Format(wxT(" %s=\"%s\""),
|
||||
name.c_str(),
|
||||
XMLEsc(value).c_str()));
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxChar *name, const wxChar *value)
|
||||
{
|
||||
WriteAttr(wxString(name), wxString(value));
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxString &name, const wxChar *value)
|
||||
{
|
||||
WriteAttr(name, wxString(value));
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxChar *name, const wxString &value)
|
||||
{
|
||||
WriteAttr(wxString(name), value);
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxString &name, int value)
|
||||
{
|
||||
Write(wxString::Format(wxT(" %s=\"%d\""),
|
||||
name.c_str(),
|
||||
value));
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxChar *name, int value)
|
||||
{
|
||||
WriteAttr(wxString(name), value);
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxString &name, bool value)
|
||||
{
|
||||
Write(wxString::Format(wxT(" %s=\"%d\""),
|
||||
name.c_str(),
|
||||
value));
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxChar *name, bool value)
|
||||
{
|
||||
WriteAttr(wxString(name), value);
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxString &name, long value)
|
||||
{
|
||||
Write(wxString::Format(wxT(" %s=\"%ld\""),
|
||||
name.c_str(),
|
||||
value));
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxChar *name, long value)
|
||||
{
|
||||
WriteAttr(wxString(name), value);
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxString &name, long long value)
|
||||
{
|
||||
Write(wxString::Format(wxT(" %s=\"%lld\""),
|
||||
name.c_str(),
|
||||
value));
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxChar *name, long long value)
|
||||
{
|
||||
WriteAttr(wxString(name), value);
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxString &name, size_t value)
|
||||
{
|
||||
Write(wxString::Format(wxT(" %s=\"%ld\""),
|
||||
name.c_str(),
|
||||
value));
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxChar *name, size_t value)
|
||||
{
|
||||
WriteAttr(wxString(name), value);
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxString &name, float value, int digits)
|
||||
{
|
||||
Write(wxString::Format(wxT(" %s=\"%s\""),
|
||||
name.c_str(),
|
||||
Internat::ToString(value, digits).c_str()));
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxChar *name, float value, int digits)
|
||||
{
|
||||
WriteAttr(wxString(name), value, digits);
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxString &name, double value, int digits)
|
||||
{
|
||||
Write(wxString::Format(wxT(" %s=\"%s\""),
|
||||
name.c_str(),
|
||||
Internat::ToString(value, digits).c_str()));
|
||||
}
|
||||
|
||||
void XMLWriter::WriteAttr(const wxChar *name, double value, int digits)
|
||||
{
|
||||
WriteAttr(wxString(name), value, digits);
|
||||
}
|
||||
|
||||
void XMLWriter::WriteData(const wxString &value)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mDepth; i++) {
|
||||
Write(wxT("\t"));
|
||||
}
|
||||
|
||||
Write(XMLEsc(value));
|
||||
}
|
||||
|
||||
void XMLWriter::WriteData(const wxChar *value)
|
||||
{
|
||||
WriteData(wxString(value));
|
||||
}
|
||||
|
||||
void XMLWriter::WriteSubTree(const wxString &value)
|
||||
{
|
||||
if (mInTag) {
|
||||
Write(wxT(">\n"));
|
||||
mInTag = false;
|
||||
mHasKids[0] = true;
|
||||
}
|
||||
|
||||
Write(value.c_str());
|
||||
}
|
||||
|
||||
void XMLWriter::WriteSubTree(const wxChar *value)
|
||||
{
|
||||
WriteSubTree(wxString(value));
|
||||
}
|
||||
|
||||
void XMLWriter::Write(const wxChar *value)
|
||||
{
|
||||
Write(wxString(value));
|
||||
}
|
||||
|
||||
// See http://www.w3.org/TR/REC-xml for reference
|
||||
wxString XMLWriter::XMLEsc(const wxString & s)
|
||||
{
|
||||
wxString result;
|
||||
int len = s.Length();
|
||||
|
||||
for(int i=0; i<len; i++) {
|
||||
wxUChar c = s.GetChar(i);
|
||||
|
||||
switch (c) {
|
||||
case wxT('\''):
|
||||
result += wxT("'");
|
||||
break;
|
||||
|
||||
case wxT('"'):
|
||||
result += wxT(""");
|
||||
break;
|
||||
|
||||
case wxT('&'):
|
||||
result += wxT("&");
|
||||
break;
|
||||
|
||||
case wxT('<'):
|
||||
result += wxT("<");
|
||||
break;
|
||||
|
||||
case wxT('>'):
|
||||
result += wxT(">");
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!wxIsprint(c)) {
|
||||
result += wxString::Format(wxT("&#x%04x;"), c);
|
||||
}
|
||||
else {
|
||||
result += c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
///
|
||||
/// XMLFileWriter class
|
||||
///
|
||||
XMLFileWriter::XMLFileWriter()
|
||||
{
|
||||
}
|
||||
|
||||
XMLFileWriter::~XMLFileWriter()
|
||||
{
|
||||
if (IsOpened()) {
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
void XMLFileWriter::Open(const wxString &name, const wxString &mode)
|
||||
{
|
||||
if (!wxFFile::Open(name, mode))
|
||||
throw new XMLFileWriterException(_("Error opening file"));
|
||||
}
|
||||
|
||||
void XMLFileWriter::Close()
|
||||
{
|
||||
while (mTagstack.GetCount()) {
|
||||
EndTag(mTagstack[0]);
|
||||
}
|
||||
|
||||
CloseWithoutEndingTags();
|
||||
}
|
||||
|
||||
void XMLFileWriter::CloseWithoutEndingTags()
|
||||
{
|
||||
// Before closing, we first flush it, because if Flush() fails because of a
|
||||
// "disk full" condition, we can still at least try to close the file.
|
||||
if (!wxFFile::Flush())
|
||||
{
|
||||
wxFFile::Close();
|
||||
throw new XMLFileWriterException(_("Error flushing file"));
|
||||
}
|
||||
|
||||
// Note that this should never fail if flushing worked.
|
||||
if (!wxFFile::Close())
|
||||
throw new XMLFileWriterException(_("Error closing file"));
|
||||
}
|
||||
|
||||
void XMLFileWriter::Write(const wxString &data)
|
||||
{
|
||||
if (!wxFFile::Write(data, wxConvUTF8))
|
||||
{
|
||||
// When writing fails, we try to close the file before throwing the
|
||||
// exception, so it can at least be deleted.
|
||||
wxFFile::Close();
|
||||
throw new XMLFileWriterException(_("Error writing to file"));
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// XMLStringWriter class
|
||||
///
|
||||
XMLStringWriter::XMLStringWriter()
|
||||
{
|
||||
}
|
||||
|
||||
XMLStringWriter::~XMLStringWriter()
|
||||
{
|
||||
}
|
||||
|
||||
void XMLStringWriter::Write(const wxString &data)
|
||||
{
|
||||
Append(data);
|
||||
}
|
||||
|
||||
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
|
||||
// version control system. Please do not modify past this point.
|
||||
//
|
||||
// Local Variables:
|
||||
// c-basic-offset: 3
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
//
|
||||
// vim: et sts=3 sw=3
|
||||
// arch-tag: 391b08e6-61f4-43ea-8431-c835c31ba86d
|
||||
Reference in New Issue
Block a user