1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-10-19 09:01:15 +02: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:
ra
2010-01-23 19:44:49 +00:00
commit e74978ba77
1011 changed files with 781704 additions and 0 deletions

152
src/xml/XMLFileReader.cpp Normal file
View File

@@ -0,0 +1,152 @@
/**********************************************************************
Audacity: A Digital Audio Editor
XMLFileReader.cpp
Dominic Mazzoni
*******************************************************************//**
\class XMLFileReader
\brief Reads a file and passes the results through an XMLTagHandler.
*//*******************************************************************/
#include <wx/defs.h>
#include <wx/ffile.h>
#include <wx/intl.h>
#include <string.h>
#include "../Internat.h"
#include "XMLFileReader.h"
XMLFileReader::XMLFileReader()
{
mParser = XML_ParserCreate(NULL);
XML_SetUserData(mParser, (void *)this);
XML_SetElementHandler(mParser, startElement, endElement);
XML_SetCharacterDataHandler(mParser, charHandler);
mBaseHandler = NULL;
mMaxDepth = 128;
mHandler = new XMLTagHandler*[mMaxDepth];
mDepth = -1;
mErrorStr = wxT("");
}
XMLFileReader::~XMLFileReader()
{
delete[] mHandler;
XML_ParserFree(mParser);
}
bool XMLFileReader::Parse(XMLTagHandler *baseHandler,
const wxString &fname)
{
wxFFile theXMLFile(fname, wxT("rb"));
if (!theXMLFile.IsOpened()) {
mErrorStr.Printf(_("Could not open file: \"%s\""), fname.c_str());
return false;
}
mBaseHandler = baseHandler;
mHandler[0] = NULL;
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 (mHandler[0])
return true;
else {
mErrorStr.Printf(_("Could not load file: \"%s\""), fname.c_str());
return false;
}
}
wxString XMLFileReader::GetErrorStr()
{
return mErrorStr;
}
// static
void XMLFileReader::startElement(void *userData, const char *name,
const char **atts)
{
XMLFileReader *This = (XMLFileReader *)userData;
This->mDepth++;
if (This->mDepth >= This->mMaxDepth) {
XMLTagHandler **newHandler = new XMLTagHandler*[This->mMaxDepth*2];
for(int i=0; i<This->mMaxDepth; i++)
newHandler[i] = This->mHandler[i];
delete[] This->mHandler;
This->mHandler = newHandler;
This->mMaxDepth *= 2;
}
if (This->mDepth==0)
This->mHandler[This->mDepth] = This->mBaseHandler;
else {
if (This->mHandler[This->mDepth-1])
This->mHandler[This->mDepth] =
This->mHandler[This->mDepth-1]->ReadXMLChild(name);
else
This->mHandler[This->mDepth] = NULL;
}
if (This->mHandler[This->mDepth]) {
if (!This->mHandler[This->mDepth]->ReadXMLTag(name, atts))
This->mHandler[This->mDepth] = 0;
}
}
// static
void XMLFileReader::endElement(void *userData, const char *name)
{
XMLFileReader *This = (XMLFileReader *)userData;
if (This->mHandler[This->mDepth])
This->mHandler[This->mDepth]->ReadXMLEndTag(name);
This->mDepth--;
}
// static
void XMLFileReader::charHandler(void *userData, const char *s, int len)
{
XMLFileReader *This = (XMLFileReader *)userData;
if (This->mHandler[This->mDepth])
This->mHandler[This->mDepth]->ReadXMLContent(s, len);
}
// 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: 0a51946d-5a9f-46c9-92d9-ee09698a9bc3

57
src/xml/XMLFileReader.h Normal file
View File

@@ -0,0 +1,57 @@
/**********************************************************************
Audacity: A Digital Audio Editor
XMLFileReader.h
Dominic Mazzoni
**********************************************************************/
#include "../Audacity.h" // to pull in USE_SYSTEM_EXPAT define
#include "expat.h"
#include "XMLTagHandler.h"
class XMLFileReader {
public:
XMLFileReader();
virtual ~XMLFileReader();
bool Parse(XMLTagHandler *baseHandler,
const wxString &fname);
wxString GetErrorStr();
// Callback functions for expat
static void startElement(void *userData, const char *name,
const char **atts);
static void endElement(void *userData, const char *name);
static void charHandler(void *userData, const char *s, int len);
private:
XML_Parser mParser;
int mMaxDepth;
int mDepth;
XMLTagHandler **mHandler;
XMLTagHandler *mBaseHandler;
wxString mErrorStr;
};
// 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: 367db03e-6d57-4749-928b-f690b8af3f4f

203
src/xml/XMLTagHandler.cpp Normal file
View File

@@ -0,0 +1,203 @@
/**********************************************************************
Audacity: A Digital Audio Editor
XMLTagHandler.cpp
Dominic Mazzoni
Vaughan Johnson
*//****************************************************************//**
\class XMLTagHandler
\brief This class is an interface which should be implemented by
classes which wish to be able to load and save themselves
using XML files.
\class XMLValueChecker
\brief XMLValueChecker implements static bool methods for checking
input values from XML files.
*//*******************************************************************/
#include "XMLTagHandler.h"
#include "../Audacity.h"
#include "../Internat.h"
#ifdef _WIN32
#include <windows.h>
#endif
#include <wx/defs.h>
#include <wx/arrstr.h>
#include <wx/filename.h>
#include "../SampleFormat.h"
#include "../Track.h"
bool XMLValueChecker::IsGoodString(const wxString str)
{
size_t len = str.Length();
int nullIndex = str.Find('\0', false);
if ((len < 2048) && // Shouldn't be any reason for longer strings, except intentional file corruption.
(nullIndex == -1)) // No null characters except terminator.
return true;
else
return false; // good place for a breakpoint
}
// "Good" means the name is well-formed and names an existing file or folder.
bool XMLValueChecker::IsGoodFileName(const wxString strFileName, const wxString strDirName /* = "" */)
{
// Test strFileName.
if (!IsGoodFileString(strFileName))
return false;
#ifdef _WIN32
if (strFileName.Length() + 1 + strDirName.Length() > MAX_PATH)
return false;
#endif
// Test the corresponding wxFileName.
wxFileName fileName(strDirName, strFileName);
return (fileName.IsOk() && fileName.FileExists());
}
bool XMLValueChecker::IsGoodSubdirName(const wxString strSubdirName, const wxString strDirName /* = "" */)
{
// Test strSubdirName.
// Note this prevents path separators, and relative path to parents (strDirName),
// so fixes vulnerability #3 in the NGS report for UmixIt,
// where an attacker could craft an AUP file with relative pathnames to get to system files, for example.
if (!IsGoodFileString(strSubdirName) || (strSubdirName == wxT(".")) || (strSubdirName == wxT("..")))
return false;
#ifdef _WIN32
if (strSubdirName.Length() + 1 + strDirName.Length() > MAX_PATH)
return false;
#endif
// Test the corresponding wxFileName.
wxFileName fileName(strDirName, strSubdirName);
return (fileName.IsOk() && fileName.DirExists());
}
bool XMLValueChecker::IsGoodPathName(const wxString strPathName)
{
// Test the corresponding wxFileName.
wxFileName fileName(strPathName);
return XMLValueChecker::IsGoodFileName(fileName.GetFullName(), fileName.GetPath(wxPATH_GET_VOLUME));
}
bool XMLValueChecker::IsGoodFileString(wxString str)
{
return (IsGoodString(str) &&
!str.IsEmpty() &&
(str.Length() <= 260) && // FILENAME_MAX is 260 in MSVC, but inconsistent across platforms, sometimes huge.
(str.Find(wxFileName::GetPathSeparator()) == -1)); // No path separator characters. //vvv (this won't work on CVS HEAD)
}
bool XMLValueChecker::IsGoodInt(const wxString strInt)
{
if (!IsGoodString(strInt))
return false;
// Check that the value won't overflow.
// Signed long: -2,147,483,648 to +2,147,483,647, i.e., -2^31 to 2^31-1
// We're strict about disallowing spaces and commas, and requiring minus sign to be first char for negative.
const size_t lenMAXABS = strlen("2147483647");
const size_t lenStrInt = strInt.Length();
if (lenStrInt > (lenMAXABS + 1))
return false;
else if ((lenStrInt == (lenMAXABS + 1)) && (strInt[0] == '-'))
{
const int digitsMAXABS[] = {2, 1, 4, 7, 4, 8, 3, 6, 4, 9};
unsigned int i;
for (i = 0; i < lenMAXABS; i++)
if (strInt[i+1] < '0' || strInt[i+1] > '9')
return false; // not a digit
for (i = 0; i < lenMAXABS; i++)
if (strInt[i+1] - '0' < digitsMAXABS[i])
return true; // number is small enough
return false;
}
else if (lenStrInt == lenMAXABS)
{
const int digitsMAXABS[] = {2, 1, 4, 7, 4, 8, 3, 6, 4, 8};
unsigned int i;
for (i = 0; i < lenMAXABS; i++)
if (strInt[i] < '0' || strInt[i+1] > '9')
return false; // not a digit
for (i = 0; i < lenMAXABS; i++)
if (strInt[i] - '0' < digitsMAXABS[i])
return true; // number is small enough
return false;
}
return true;
}
bool XMLValueChecker::IsValidChannel(const int nValue)
{
return (nValue >= Track::LeftChannel) && (nValue <= Track::MonoChannel);
}
bool XMLValueChecker::IsValidSampleFormat(const int nValue)
{
return (nValue == int16Sample) || (nValue == int24Sample) || (nValue == floatSample);
}
bool XMLTagHandler::ReadXMLTag(const char *tag, const char **attrs)
{
wxArrayString tmp_attrs;
while (*attrs) {
const char *s = *attrs++;
tmp_attrs.Add(UTF8CTOWX(s));
}
// JKC: Previously the next line was:
// const char **out_attrs = new char (const char *)[tmp_attrs.GetCount()+1];
// however MSVC doesn't like the constness in this position, so this is now
// added by a cast after creating the array of pointers-to-non-const chars.
const wxChar **out_attrs = (const wxChar**)new wxChar *[tmp_attrs.GetCount()+1];
for (size_t i=0; i<tmp_attrs.GetCount(); i++) {
out_attrs[i] = tmp_attrs[i].c_str();
}
out_attrs[tmp_attrs.GetCount()] = 0;
bool result = HandleXMLTag(UTF8CTOWX(tag).c_str(), out_attrs);
delete[] out_attrs;
return result;
}
void XMLTagHandler::ReadXMLEndTag(const char *tag)
{
HandleXMLEndTag(UTF8CTOWX(tag).c_str());
}
void XMLTagHandler::ReadXMLContent(const char *s, int len)
{
HandleXMLContent(wxString(s, wxConvUTF8, len));
}
XMLTagHandler *XMLTagHandler::ReadXMLChild(const char *tag)
{
return HandleXMLChild(UTF8CTOWX(tag).c_str());
}
// 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: 6aabae58-19bd-4b3a-aa6c-08432a7e106e

100
src/xml/XMLTagHandler.h Normal file
View File

@@ -0,0 +1,100 @@
/**********************************************************************
Audacity: A Digital Audio Editor
XMLTagHandler.h
Dominic Mazzoni
Vaughan Johnson
The XMLTagHandler class is an interface which should be implemented by
classes which wish to be able to load and save themselves
using XML files.
The XMLValueChecker class implements static bool methods for checking
input values from XML files.
**********************************************************************/
#ifndef __AUDACITY_XML_TAG_HANDLER__
#define __AUDACITY_XML_TAG_HANDLER__
#include "../Audacity.h"
#include <wx/string.h>
#include <stdio.h>
#include "XMLWriter.h"
class XMLValueChecker
{
public:
// "Good" means well-formed and for the file-related functions, names an existing file or folder.
// These are used in HandleXMLTag and BuildFomXML methods to check the input for
// security vulnerabilites, per the NGS report for UmixIt.
static bool IsGoodString(const wxString str);
static bool IsGoodFileName(const wxString strFileName, const wxString strDirName = wxEmptyString);
static bool IsGoodSubdirName(const wxString strSubdirName, const wxString strDirName = wxEmptyString);
static bool IsGoodPathName(const wxString strPathName);
// Note that because wxString::ToLong does additional testing, IsGoodInt doesn't duplicate
// that testing, so use wxString::ToLong after IsGoodInt, not just atoi.
static bool IsGoodInt(const wxString strInt);
static bool IsValidChannel(const int nValue);
static bool IsValidSampleFormat(const int nValue); // true if nValue is one sampleFormat enum values
static bool IsGoodFileString(wxString str);
};
class AUDACITY_DLL_API XMLTagHandler {
public:
XMLTagHandler(){};
virtual ~XMLTagHandler(){};
//
// Methods to override
//
// This method will be called on your class if your class has
// been registered to handle this particular tag. Parse the
// tag and the attribute-value pairs (null-terminated), and
// return true on success, and false on failure. If you return
// false, you will not get any calls about children.
virtual bool HandleXMLTag(const wxChar *tag, const wxChar **attrs) = 0;
// This method will be called when a closing tag is encountered.
// It is optional to override this method.
virtual void HandleXMLEndTag(const wxChar *tag) {}
// This method will be called when element content has been
// encountered.
// It is optional to override this method.
virtual void HandleXMLContent(const wxString & content) {}
// If the XML document has children of your tag, this method
// should be called. Typically you should construct a new
// object for the child, insert it into your own local data
// structures, and then return it. If you do not wish to
// handle this child, return NULL and it will be ignored.
virtual XMLTagHandler *HandleXMLChild(const wxChar *tag) = 0;
// These functions recieve data from expat. They do charset
// conversion and then pass the data to the handlers above.
bool ReadXMLTag(const char *tag, const char **attrs);
void ReadXMLEndTag(const char *tag);
void ReadXMLContent(const char *s, int len);
XMLTagHandler *ReadXMLChild(const char *tag);
};
#endif // define __AUDACITY_XML_TAG_HANDLER__
// 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: 7c9a9baa-c546-42de-afaa-d87e5e13bf5a

369
src/xml/XMLWriter.cpp Normal file
View 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("&apos;");
break;
case wxT('"'):
result += wxT("&quot;");
break;
case wxT('&'):
result += wxT("&amp;");
break;
case wxT('<'):
result += wxT("&lt;");
break;
case wxT('>'):
result += wxT("&gt;");
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

141
src/xml/XMLWriter.h Normal file
View File

@@ -0,0 +1,141 @@
/**********************************************************************
Audacity: A Digital Audio Editor
XMLWriter.h
Leland Lucius
**********************************************************************/
#ifndef __AUDACITY_XML_XML_FILE_WRITER__
#define __AUDACITY_XML_XML_FILE_WRITER__
#include <wx/ffile.h>
#include <wx/dynarray.h>
///
/// XMLWriter
///
class XMLWriter {
public:
XMLWriter();
virtual ~XMLWriter();
void StartTag(const wxString &name);
void EndTag(const wxString &name);
void WriteAttr(const wxString &name, const wxString &value);
void WriteAttr(const wxChar *name, const wxChar *value);
void WriteAttr(const wxString &name, const wxChar *value);
void WriteAttr(const wxChar *name, const wxString &value);
void WriteAttr(const wxString &name, int value);
void WriteAttr(const wxChar *name, int value);
void WriteAttr(const wxString &name, bool value);
void WriteAttr(const wxChar *name, bool value);
void WriteAttr(const wxString &name, long value);
void WriteAttr(const wxChar *name, long value);
void WriteAttr(const wxString &name, long long value);
void WriteAttr(const wxChar *name, long long value);
void WriteAttr(const wxString &name, size_t value);
void WriteAttr(const wxChar *name, size_t value);
void WriteAttr(const wxString &name, float value, int digits = -1);
void WriteAttr(const wxChar *name, float value, int digits = -1);
void WriteAttr(const wxString &name, double value, int digits = -1);
void WriteAttr(const wxChar *name, double value, int digits = -1);
void WriteData(const wxString &value);
void WriteData(const wxChar *value);
void WriteSubTree(const wxString &value);
void WriteSubTree(const wxChar *value);
void Write(const wxChar *data);
virtual void Write(const wxString &data) = 0;
// Escape a string, replacing certain characters with their
// XML encoding, i.e. '<' becomes '&lt;'
wxString XMLEsc(const wxString & s);
protected:
bool mInTag;
int mDepth;
wxArrayString mTagstack;
wxArrayInt mHasKids;
};
///
/// XMLFileWriter
///
class XMLFileWriter:public wxFFile, public XMLWriter {
public:
XMLFileWriter();
virtual ~XMLFileWriter();
/// Open the file. Might throw XMLFileWriterException.
void Open(const wxString &name, const wxString &mode);
/// Close file. Might throw XMLFileWriterException.
void Close();
/// Close file without automatically ending tags.
/// Might throw XMLFileWriterException.
void CloseWithoutEndingTags(); // for auto-save files
/// Write to file. Might throw XMLFileWriterException.
void Write(const wxString &data);
private:
};
///
/// Exception thrown by various XMLFileWriter methods
///
class XMLFileWriterException
{
public:
XMLFileWriterException(const wxString& message) { mMessage = message; }
wxString GetMessage() const { return mMessage; }
protected:
wxString mMessage;
};
///
/// XMLStringWriter
///
class XMLStringWriter:public wxString, public XMLWriter {
public:
XMLStringWriter();
virtual ~XMLStringWriter();
void Write(const wxString &data);
wxString Get();
private:
};
#endif
// 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

View File

@@ -0,0 +1,92 @@
<!--DTD for Audacity Project files, as created by Audacity version 1.3.0 -->
<!--For more information: http://audacity.sourceforge.net/xml/ -->
<!ELEMENT project (tags, (wavetrack | labeltrack | timetrack)*)>
<!ATTLIST project projname CDATA #REQUIRED>
<!ATTLIST project version CDATA #REQUIRED>
<!ATTLIST project audacityversion CDATA #REQUIRED>
<!ATTLIST project sel0 CDATA #REQUIRED>
<!ATTLIST project sel1 CDATA #REQUIRED>
<!ATTLIST project vpos CDATA #REQUIRED>
<!ATTLIST project h CDATA #REQUIRED>
<!ATTLIST project zoom CDATA #REQUIRED>
<!ATTLIST project rate CDATA #REQUIRED>
<!ELEMENT tags EMPTY>
<!ATTLIST tags title CDATA #REQUIRED>
<!ATTLIST tags artist CDATA #REQUIRED>
<!ATTLIST tags album CDATA #REQUIRED>
<!ATTLIST tags track CDATA #REQUIRED>
<!ATTLIST tags year CDATA #REQUIRED>
<!ATTLIST tags genre CDATA #REQUIRED>
<!ATTLIST tags comments CDATA #REQUIRED>
<!ATTLIST tags id3v2 (0|1) #REQUIRED>
<!ELEMENT labeltrack (label*)>
<!ATTLIST labeltrack name CDATA #REQUIRED>
<!ATTLIST labeltrack numlabels CDATA #REQUIRED>
<!ELEMENT label EMPTY>
<!ATTLIST label t CDATA #REQUIRED>
<!ATTLIST label t1 CDATA #REQUIRED>
<!ATTLIST label title CDATA #REQUIRED>
<!ELEMENT timetrack (envelope)>
<!ATTLIST timetrack name CDATA #REQUIRED>
<!ATTLIST timetrack channel CDATA #REQUIRED>
<!ATTLIST timetrack offset CDATA #REQUIRED>
<!ELEMENT wavetrack (waveclip*)>
<!ATTLIST wavetrack name CDATA #REQUIRED>
<!ATTLIST wavetrack channel CDATA #REQUIRED>
<!ATTLIST wavetrack linked CDATA #REQUIRED>
<!ATTLIST wavetrack offset CDATA #REQUIRED>
<!ATTLIST wavetrack rate CDATA #REQUIRED>
<!ATTLIST wavetrack gain CDATA #REQUIRED>
<!ATTLIST wavetrack pan CDATA #REQUIRED>
<!ATTLIST wavetrack mute CDATA "0">
<!ATTLIST wavetrack solo CDATA "0">
<!ELEMENT waveclip (sequence, envelope)>
<!ATTLIST waveclip offset CDATA #REQUIRED>
<!ELEMENT sequence (waveblock*)>
<!ATTLIST sequence maxsamples CDATA #REQUIRED>
<!ATTLIST sequence sampleformat CDATA #REQUIRED>
<!ATTLIST sequence numsamples CDATA #REQUIRED>
<!ELEMENT waveblock (simpleblockfile | silentblockfile | legacyblockfile | pcmaliasblockfile)>
<!ATTLIST waveblock start CDATA #REQUIRED>
<!ELEMENT simpleblockfile EMPTY>
<!ATTLIST simpleblockfile filename CDATA #REQUIRED>
<!ATTLIST simpleblockfile len CDATA #REQUIRED>
<!ATTLIST simpleblockfile min CDATA #REQUIRED>
<!ATTLIST simpleblockfile max CDATA #REQUIRED>
<!ATTLIST simpleblockfile rms CDATA #REQUIRED>
<!ELEMENT silentblockfile EMPTY>
<!ATTLIST silentblockfile len CDATA #REQUIRED>
<!ELEMENT legacyblockfile EMPTY>
<!ATTLIST legacyblockfile name CDATA #REQUIRED>
<!ATTLIST legacyblockfile len CDATA #REQUIRED>
<!ATTLIST legacyblockfile summarylen CDATA #REQUIRED>
<!ATTLIST legacyblockfile norms CDATA "0">
<!ELEMENT pcmaliasblockfile EMPTY>
<!ATTLIST pcmaliasblockfile summaryfile CDATA #REQUIRED>
<!ATTLIST pcmaliasblockfile aliasfile CDATA #REQUIRED>
<!ATTLIST pcmaliasblockfile aliasstart CDATA #REQUIRED>
<!ATTLIST pcmaliasblockfile aliaslen CDATA #REQUIRED>
<!ATTLIST pcmaliasblockfile aliaschannel CDATA #REQUIRED>
<!ATTLIST pcmaliasblockfile min CDATA #REQUIRED>
<!ATTLIST pcmaliasblockfile max CDATA #REQUIRED>
<!ATTLIST pcmaliasblockfile rms CDATA #REQUIRED>
<!ELEMENT envelope (controlpoint*)>
<!ATTLIST envelope numpoints CDATA #REQUIRED>
<!ELEMENT controlpoint EMPTY>
<!ATTLIST controlpoint t CDATA #REQUIRED>
<!ATTLIST controlpoint val CDATA #REQUIRED>