commit a4fbe0dfd59780f77e5902736a616cda27efde17
parent cf8389d298b33d65fa26ed586aed5aac05a0be4e
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Thu, 13 May 2010 12:16:19 -0400
XML: Memory leak
Diffstat:
4 files changed, 65 insertions(+), 42 deletions(-)
diff --git a/src/Misc/Bank.cpp b/src/Misc/Bank.cpp
@@ -609,11 +609,10 @@ int Bank::addtobank(int pos, const char *filename, const char *name)
//see if PADsynth is used
if(config.cfg.CheckPADsynth) {
- XMLwrapper *xml = new XMLwrapper();
- xml->loadXMLfile(ins[pos].filename);
+ XMLwrapper xml;
+ xml.loadXMLfile(ins[pos].filename);
- ins[pos].info.PADsynth_used = xml->hasPadSynth();
- delete xml;
+ ins[pos].info.PADsynth_used = xml.hasPadSynth();
}
else
ins[pos].info.PADsynth_used = false;
diff --git a/src/Misc/Config.cpp b/src/Misc/Config.cpp
@@ -225,110 +225,109 @@ void Config::clearpresetsdirlist()
void Config::readConfig(const char *filename)
{
- XMLwrapper *xmlcfg = new XMLwrapper();
- if(xmlcfg->loadXMLfile(filename) < 0)
+ XMLwrapper xmlcfg;
+ if(xmlcfg.loadXMLfile(filename) < 0)
return;
- if(xmlcfg->enterbranch("CONFIGURATION")) {
- cfg.SampleRate = xmlcfg->getpar("sample_rate",
+ if(xmlcfg.enterbranch("CONFIGURATION")) {
+ cfg.SampleRate = xmlcfg.getpar("sample_rate",
cfg.SampleRate,
4000,
1024000);
- cfg.SoundBufferSize = xmlcfg->getpar("sound_buffer_size",
+ cfg.SoundBufferSize = xmlcfg.getpar("sound_buffer_size",
cfg.SoundBufferSize,
16,
8192);
- cfg.OscilSize = xmlcfg->getpar("oscil_size",
+ cfg.OscilSize = xmlcfg.getpar("oscil_size",
cfg.OscilSize,
MAX_AD_HARMONICS * 2,
131072);
- cfg.SwapStereo = xmlcfg->getpar("swap_stereo",
+ cfg.SwapStereo = xmlcfg.getpar("swap_stereo",
cfg.SwapStereo,
0,
1);
- cfg.BankUIAutoClose = xmlcfg->getpar("bank_window_auto_close",
+ cfg.BankUIAutoClose = xmlcfg.getpar("bank_window_auto_close",
cfg.BankUIAutoClose,
0,
1);
- cfg.DumpNotesToFile = xmlcfg->getpar("dump_notes_to_file",
+ cfg.DumpNotesToFile = xmlcfg.getpar("dump_notes_to_file",
cfg.DumpNotesToFile,
0,
1);
- cfg.DumpAppend = xmlcfg->getpar("dump_append",
+ cfg.DumpAppend = xmlcfg.getpar("dump_append",
cfg.DumpAppend,
0,
1);
- xmlcfg->getparstr("dump_file", cfg.DumpFile, MAX_STRING_SIZE);
+ xmlcfg.getparstr("dump_file", cfg.DumpFile, MAX_STRING_SIZE);
- cfg.GzipCompression = xmlcfg->getpar("gzip_compression",
+ cfg.GzipCompression = xmlcfg.getpar("gzip_compression",
cfg.GzipCompression,
0,
9);
- xmlcfg->getparstr("bank_current", cfg.currentBankDir, MAX_STRING_SIZE);
- cfg.Interpolation = xmlcfg->getpar("interpolation",
+ xmlcfg.getparstr("bank_current", cfg.currentBankDir, MAX_STRING_SIZE);
+ cfg.Interpolation = xmlcfg.getpar("interpolation",
cfg.Interpolation,
0,
1);
- cfg.CheckPADsynth = xmlcfg->getpar("check_pad_synth",
+ cfg.CheckPADsynth = xmlcfg.getpar("check_pad_synth",
cfg.CheckPADsynth,
0,
1);
- cfg.UserInterfaceMode = xmlcfg->getpar("user_interface_mode",
+ cfg.UserInterfaceMode = xmlcfg.getpar("user_interface_mode",
cfg.UserInterfaceMode,
0,
2);
- cfg.VirKeybLayout = xmlcfg->getpar("virtual_keyboard_layout",
+ cfg.VirKeybLayout = xmlcfg.getpar("virtual_keyboard_layout",
cfg.VirKeybLayout,
0,
10);
//get bankroot dirs
for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) {
- if(xmlcfg->enterbranch("BANKROOT", i)) {
+ if(xmlcfg.enterbranch("BANKROOT", i)) {
cfg.bankRootDirList[i] = new char[MAX_STRING_SIZE];
- xmlcfg->getparstr("bank_root",
+ xmlcfg.getparstr("bank_root",
cfg.bankRootDirList[i],
MAX_STRING_SIZE);
- xmlcfg->exitbranch();
+ xmlcfg.exitbranch();
}
}
//get preset root dirs
for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) {
- if(xmlcfg->enterbranch("PRESETSROOT", i)) {
+ if(xmlcfg.enterbranch("PRESETSROOT", i)) {
cfg.presetsDirList[i] = new char[MAX_STRING_SIZE];
- xmlcfg->getparstr("presets_root",
+ xmlcfg.getparstr("presets_root",
cfg.presetsDirList[i],
MAX_STRING_SIZE);
- xmlcfg->exitbranch();
+ xmlcfg.exitbranch();
}
}
//linux stuff
- xmlcfg->getparstr("linux_oss_wave_out_dev",
+ xmlcfg.getparstr("linux_oss_wave_out_dev",
cfg.LinuxOSSWaveOutDev,
MAX_STRING_SIZE);
- xmlcfg->getparstr("linux_oss_seq_in_dev",
+ xmlcfg.getparstr("linux_oss_seq_in_dev",
cfg.LinuxOSSSeqInDev,
MAX_STRING_SIZE);
//windows stuff
- cfg.WindowsWaveOutId = xmlcfg->getpar("windows_wave_out_id",
+ cfg.WindowsWaveOutId = xmlcfg.getpar("windows_wave_out_id",
cfg.WindowsWaveOutId,
0,
winwavemax);
- cfg.WindowsMidiInId = xmlcfg->getpar("windows_midi_in_id",
+ cfg.WindowsMidiInId = xmlcfg.getpar("windows_midi_in_id",
cfg.WindowsMidiInId,
0,
winmidimax);
- xmlcfg->exitbranch();
+ xmlcfg.exitbranch();
}
- delete (xmlcfg);
cfg.OscilSize = (int) pow(2, ceil(log(cfg.OscilSize - 1.0) / log(2.0)));
}
diff --git a/src/Misc/XMLwrapper.cpp b/src/Misc/XMLwrapper.cpp
@@ -140,7 +140,7 @@ XMLwrapper::XMLwrapper()
XMLwrapper::~XMLwrapper()
{
- if(tree != NULL)
+ if(tree)
mxmlDelete(tree);
}
@@ -295,6 +295,13 @@ void XMLwrapper::endbranch()
}
+//workaround for memory leak
+const char *trimLeadingWhite(const char *c)
+{
+ while(isspace(*c))
+ ++c;
+ return c;
+}
/* LOAD XML members */
@@ -306,15 +313,14 @@ int XMLwrapper::loadXMLfile(const string &filename)
const char *xmldata = doloadfile(filename.c_str());
if(xmldata == NULL)
- return -1; //the file could not be loaded or uncompressed
+ return -1; //the file could not be loaded or uncompressed
- root = tree = mxmlLoadString(NULL, xmldata, MXML_OPAQUE_CALLBACK);
+ root = tree = mxmlLoadString(NULL, trimLeadingWhite(xmldata), MXML_OPAQUE_CALLBACK);
- delete [] xmldata;
+ delete[] xmldata;
if(tree == NULL)
- return -2; //this is not XML
-
+ return -2; //this is not XML
node = root = mxmlFindElement(tree,
tree,
@@ -323,7 +329,7 @@ int XMLwrapper::loadXMLfile(const string &filename)
NULL,
MXML_DESCEND);
if(root == NULL)
- return -3; //the XML doesnt embbed zynaddsubfx data
+ return -3; //the XML doesnt embbed zynaddsubfx data
//fetch version information
version.Major = stringTo<int>(mxmlElementGetAttr(root, "version-major"));
@@ -335,7 +341,6 @@ int XMLwrapper::loadXMLfile(const string &filename)
cout << "loadXMLfile() version: " << version.Major << '.'
<< version.Minor << '.' << version.Revision << endl;
-
return 0;
}
@@ -379,7 +384,7 @@ bool XMLwrapper::putXMLdata(const char *xmldata)
if(xmldata == NULL)
return false;
- root = tree = mxmlLoadString(NULL, xmldata, MXML_OPAQUE_CALLBACK);
+ root = tree = mxmlLoadString(NULL, trimLeadingWhite(xmldata), MXML_OPAQUE_CALLBACK);
if(tree == NULL)
return false;
diff --git a/src/Tests/XMLwrapperTest.h b/src/Tests/XMLwrapperTest.h
@@ -21,6 +21,8 @@
*/
#include <cxxtest/TestSuite.h>
#include "../Misc/XMLwrapper.h"
+#include <string>
+using namespace std;
class XMLwrapperTest:public CxxTest::TestSuite
{
@@ -36,6 +38,24 @@ class XMLwrapperTest:public CxxTest::TestSuite
TS_ASSERT_EQUALS(xmla->getpar("my Pa*_ramet@er", 0, -200, 200), 75);
}
+ //here to verify that no leaks occur
+ void testLoad() {
+ string location = string(SOURCE_DIR) + string("/Tests/guitar-adnote.xmz");
+ xmla->loadXMLfile(location);
+ }
+
+ void testAnotherLoad()
+ {
+ string dat = "\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
+<!DOCTYPE ZynAddSubFX-data>\n\
+<ZynAddSubFX-data version-major=\"2\" version-minor=\"4\"\n\
+version-revision=\"1\" ZynAddSubFX-author=\"Nasca Octavian Paul\">\n\
+</ZynAddSubFX-data>\n";
+ xmlb->putXMLdata(dat.c_str());
+#warning todo contact mxml people about possible memoryleak when
+#warning mxmlLoadString is giving something starting with a newline
+ }
+
void tearDown() {
delete xmla;
delete xmlb;