From 8c585aa006741b95c1175afcdb01cdd3d8d2d7db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Nusser?= <andre.nusser@googlemail.com>
Date: Wed, 23 Mar 2016 18:24:29 +0100
Subject: Do the file related actions in SAXParser.

---
 src/audioinputenginemidi.cc |  4 +--
 src/configparser.h          |  4 +--
 src/drumgizmo.cc            |  6 ++---
 src/drumkitparser.cc        | 56 +++++++++++---------------------------
 src/drumkitparser.h         |  8 +++---
 src/instrumentparser.cc     | 32 ++++------------------
 src/instrumentparser.h      |  8 +++---
 src/midimapparser.cc        | 26 ------------------
 src/midimapparser.h         |  9 -------
 src/saxparser.cc            | 65 +++++++++++++++++++++------------------------
 src/saxparser.h             | 12 ++++-----
 11 files changed, 70 insertions(+), 160 deletions(-)

diff --git a/src/audioinputenginemidi.cc b/src/audioinputenginemidi.cc
index d81a49b..e3cb796 100644
--- a/src/audioinputenginemidi.cc
+++ b/src/audioinputenginemidi.cc
@@ -58,8 +58,8 @@ bool AudioInputEngineMidi::loadMidiMap(std::string file, Instruments &instrument
 
   if(f == "") return false;
 
-  MidiMapParser p(f);
-  if(p.parse()) {
+  MidiMapParser p;
+  if(p.parseFile(f)) {
     return false;
   }
 
diff --git a/src/configparser.h b/src/configparser.h
index b8bde05..79f0cb1 100644
--- a/src/configparser.h
+++ b/src/configparser.h
@@ -30,8 +30,8 @@
 
 #include "saxparser.h"
 
-class ConfigParser :
-	public SAXParser
+class ConfigParser
+	: public SAXParser
 {
 public:
 	ConfigParser();
diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc
index 159b01b..51cee18 100644
--- a/src/drumgizmo.cc
+++ b/src/drumgizmo.cc
@@ -81,8 +81,8 @@ bool DrumGizmo::loadkit(std::string file)
 	// Delete all Channels, Instruments, Samples and AudioFiles.
 	kit.clear();
 
-	DrumKitParser parser(file, kit);
-	if(parser.parse())
+	DrumKitParser parser(kit);
+	if(parser.parseFile(file))
 	{
 		ERR(drumgizmo, "Drumkit parser failed: %s\n", file.c_str());
 		return false;
@@ -709,7 +709,7 @@ bool DrumGizmo::setConfigString(std::string cfg)
 
 	std::string dkf;
 	ConfigParser p;
-	if(p.parse(cfg))
+	if(p.parseString(cfg))
 	{
 	 ERR(drumgizmo, "Config parse error.\n");
 	 return false;
diff --git a/src/drumkitparser.cc b/src/drumkitparser.cc
index 2d0262d..595cd41 100644
--- a/src/drumkitparser.cc
+++ b/src/drumkitparser.cc
@@ -34,17 +34,21 @@
 #include "path.h"
 #include "drumgizmo.h"
 
-DrumKitParser::DrumKitParser(const std::string& file, DrumKit& k)
-	: kit(k)
+DrumKitParser::DrumKitParser(DrumKit& kit)
+	: kit(kit)
  	, refs(REFSFILE)
 {
-	std::string kitfile = file;
+}
+
+int DrumKitParser::parseFile(const std::string& filename)
+{
+	auto edited_filename(filename);
 
 	if(refs.load())
 	{
-		if(file.size() > 1 && file[0] == '@')
+		if(filename.size() > 1 && filename[0] == '@')
 		{
-			kitfile = refs.getValue(file.substr(1));
+			edited_filename	= refs.getValue(filename.substr(1));
 		}
 	}
 	else
@@ -52,28 +56,14 @@ DrumKitParser::DrumKitParser(const std::string& file, DrumKit& k)
 		ERR(drumkitparser, "Error reading refs.conf");
 	}
 
-	//  instr = NULL;
-	path = getPath(kitfile);
-
-	fd = fopen(kitfile.c_str(), "r");
-
-	//  DEBUG(kitparser, "Parsing drumkit in %s\n", kitfile.c_str());
-
-	if(!fd)
-	{
-		return;
-	}
-
-	kit._file = file;
-}
+	path = getPath(edited_filename);
+	auto result = SAXParser::parseFile(filename);
 
-DrumKitParser::~DrumKitParser()
-{
-	if(fd)
-	{
-		fclose(fd);
+	if (result == 0) {
+		kit._file = edited_filename;
 	}
 
+	return result;
 }
 
 void DrumKitParser::startTag(const std::string& name, const attr_t& attr)
@@ -193,8 +183,8 @@ void DrumKitParser::endTag(const std::string& name)
 		Instrument* i = new Instrument();
 		i->setGroup(instr_group);
 		//    Instrument &i = kit.instruments[kit.instruments.size() - 1];
-		InstrumentParser parser(path + "/" + instr_file, *i);
-		parser.parse();
+		InstrumentParser parser(*i);
+		parser.parseFile(path + "/" + instr_file);
 		kit.instruments.push_back(i);
 
 		// Assign kit channel numbers to instruments channels.
@@ -233,17 +223,3 @@ void DrumKitParser::endTag(const std::string& name)
 		channelmap.clear();
 	}
 }
-
-int DrumKitParser::readData(std::string& data, std::size_t size)
-{
-	if(!fd)
-	{
-		return -1;
-	}
-
-	data.resize(size);
-	auto nr_of_bytes_read = fread((void*)data.data(), 1, size, fd);
-	data.resize(nr_of_bytes_read);
-	return nr_of_bytes_read;
-	return fread((char*)data.c_str(), 1, size, fd);
-}
diff --git a/src/drumkitparser.h b/src/drumkitparser.h
index 1c49ed8..f857590 100644
--- a/src/drumkitparser.h
+++ b/src/drumkitparser.h
@@ -34,17 +34,15 @@ class DrumKitParser
 	: public SAXParser
 {
 public:
-	DrumKitParser(const std::string& kitfile, DrumKit& kit);
-	~DrumKitParser();
+	DrumKitParser(DrumKit& kit);
+
+	virtual int parseFile(const std::string& filename) override;
 
 protected:
 	void startTag(const std::string& name, const attr_t& attributes) override;
 	void endTag(const std::string& name) override;
 
-	int readData(std::string& data, std::size_t size) override;
-
 private:
-	FILE* fd;
 	DrumKit& kit;
 	std::string path;
 
diff --git a/src/instrumentparser.cc b/src/instrumentparser.cc
index 8c3c737..268f8f3 100644
--- a/src/instrumentparser.cc
+++ b/src/instrumentparser.cc
@@ -35,26 +35,17 @@
 
 #include "nolocale.h"
 
-InstrumentParser::InstrumentParser(const std::string& file, Instrument& i)
+InstrumentParser::InstrumentParser(Instrument& i)
 	: instrument(i)
 {
-	//  DEBUG(instrparser,"Parsing instrument in %s\n", file.c_str());
-	path = getPath(file);
-	fd = fopen(file.c_str(), "r");
 
-	if(!fd)
-	{
-		ERR(instrparser, "The following instrument file could not be opened: %s\n", file.c_str());
-		return;
-	}
 }
 
-InstrumentParser::~InstrumentParser()
+int InstrumentParser::parseFile(const std::string& filename)
 {
-	if(fd)
-	{
-		fclose(fd);
-	}
+	path = getPath(filename);
+
+	return SAXParser::parseFile(filename);
 }
 
 void InstrumentParser::startTag(const std::string& name, const attr_t& attr)
@@ -233,16 +224,3 @@ void InstrumentParser::endTag(const std::string& name)
 		instrument.finalise();
 	}
 }
-
-int InstrumentParser::readData(std::string& data, std::size_t size)
-{
-	if(!fd)
-	{
-		return -1;
-	}
-	
-	data.resize(size);
-	auto nr_of_bytes_read = fread((void*)data.data(), 1, size, fd);
-	data.resize(nr_of_bytes_read);
-	return nr_of_bytes_read;
-}
diff --git a/src/instrumentparser.h b/src/instrumentparser.h
index a203444..965694a 100644
--- a/src/instrumentparser.h
+++ b/src/instrumentparser.h
@@ -35,19 +35,17 @@ class InstrumentParser
 	: public SAXParser
 {
 public:
-	InstrumentParser(const std::string& instrfile, Instrument &instrument);
-	~InstrumentParser();
+	InstrumentParser(Instrument &instrument);
+
+	virtual int parseFile(const std::string& filename) override;
 
 	std::vector<InstrumentChannel*> channellist;
 
 protected:
-	int readData(std::string& data, std::size_t size) override;
-
 	virtual void startTag(const std::string& name, const attr_t& attr) override;
 	virtual void endTag(const std::string& name) override;
 
 private:
-	FILE* fd{nullptr};
 	Instrument& instrument;
 	Sample* s{nullptr};
 
diff --git a/src/midimapparser.cc b/src/midimapparser.cc
index 38a4124..ec4c10d 100644
--- a/src/midimapparser.cc
+++ b/src/midimapparser.cc
@@ -26,19 +26,6 @@
  */
 #include "midimapparser.h"
 
-MidiMapParser::MidiMapParser(const std::string& file)
-{
-	fd = fopen(file.c_str(), "r");
-}
-
-MidiMapParser::~MidiMapParser()
-{
-	if(fd)
-	{
-		fclose(fd);
-	}
-}
-
 void MidiMapParser::startTag(const std::string& name, const attr_t& attr)
 {
 	if(name == "map")
@@ -49,16 +36,3 @@ void MidiMapParser::startTag(const std::string& name, const attr_t& attr)
 		}
 	}
 }
-
-int MidiMapParser::readData(std::string& data, std::size_t size)
-{
-	if(!fd)
-	{
-		return -1;
-	}
-
-	data.resize(size);
-	auto nr_of_bytes_read = fread((void*)data.data(), 1, size, fd);
-	data.resize(nr_of_bytes_read);
-	return nr_of_bytes_read;
-}
diff --git a/src/midimapparser.h b/src/midimapparser.h
index 02e79df..740cb60 100644
--- a/src/midimapparser.h
+++ b/src/midimapparser.h
@@ -35,16 +35,7 @@ class MidiMapParser
 	: public SAXParser
 {
 public:
-	MidiMapParser(const std::string& file);
-	~MidiMapParser();
-
 	void startTag(const std::string& name, const attr_t& attr) override;
 
 	midimap_t midimap;
-
-protected:
-	int readData(std::string& data, size_t size) override;
-
-private:
-	FILE* fd;
 };
diff --git a/src/saxparser.cc b/src/saxparser.cc
index e59a1fe..e32143d 100644
--- a/src/saxparser.cc
+++ b/src/saxparser.cc
@@ -26,9 +26,10 @@
  */
 #include "saxparser.h"
 
-#include <stdio.h>
 #include <string.h>
 #include <hugin.hpp>
+#include <sstream>
+#include <iostream>
 
 SAXParser::SAXParser()
 {
@@ -50,54 +51,48 @@ SAXParser::~SAXParser()
 	XML_ParserFree(p);
 }
 
-int SAXParser::parse()
+int SAXParser::parseFile(const std::string& filename)
 {
-	DEBUG(sax, "parse()\n");
-
-	std::string buf;
-	int len;
-
-	do {
-		len = readData(buf, 32);
-		if(len <= -1) {
-			parseError("", 0, "Could not read data", 0);
-			return 1;
-		}
-		if(!XML_Parse(p, (char*)buf.c_str(), len, len == 0)) {
-			parseError(buf, len, XML_ErrorString(XML_GetErrorCode(p)),
-				   (int)XML_GetCurrentLineNumber(p));
-			return 1;
-		}
-
-		buf.clear();
-	} while(len);
+	if(filename.empty())
+	{
+		return 0;
+	}
+
+	std::ifstream file(filename, std::ifstream::in);
+
+	if(!file.is_open()) {
+		return 1;
+	}
+
+	std::stringstream ss;
+	ss << file.rdbuf();
+	std::string str = ss.str();
+
+	parseString(str, filename);
 
 	return 0;
 }
 
-int SAXParser::parse(const std::string& buffer)
+int SAXParser::parseString(const std::string& str, const std::string& xml_source_name)
 {
-	DEBUG(sax, "parse(buffer %d bytes)\n", (int)buffer.length());
+	DEBUG(sax, "parse(buffer %d bytes)\n", (int)str.length());
 
-	if(!XML_Parse(p, buffer.c_str(), buffer.length(), true)) {
-		parseError(buffer, buffer.length(),
-			   XML_ErrorString(XML_GetErrorCode(p)),
-			   (int)XML_GetCurrentLineNumber(p));
+	if(!XML_Parse(p, str.c_str(), str.length(), true)) {
+		parseError(str, XML_ErrorString(XML_GetErrorCode(p)),
+		           xml_source_name, (int)XML_GetCurrentLineNumber(p));
 		return 1;
 	}
 
 	return 0;
 }
 
-void SAXParser::parseError(const std::string& buf, std::size_t len, const std::string& error, std::size_t lineno)
+void SAXParser::parseError(const std::string& buf, const std::string& error, const std::string& xml_source_name, std::size_t lineno)
 {
-	fprintf(stderr, "SAXParser error at line %d: %s\n", (int)lineno, error.c_str());
-	fprintf(stderr, "Buffer %u bytes: \n[\n", (int)len);
-
-	fwrite((char*)buf.c_str(), len, 1, stderr);
-
-	fprintf(stderr, "\n]\n");
-	fflush(stderr);
+	std::cerr << "SAXParser error trying to parse from source: " << xml_source_name << "\n";
+	std::cerr << "At line " << lineno << ": " << error << "\n";
+	std::cerr << "Buffer " << buf.size() << " bytes: \n[\n";
+	std::cerr << buf;
+	std::cerr << "\n]" << std::endl;
 }
 
 void SAXParser::character_hndl(void* p, const XML_Char* s, int len)
diff --git a/src/saxparser.h b/src/saxparser.h
index c43f00a..b4d9823 100644
--- a/src/saxparser.h
+++ b/src/saxparser.h
@@ -29,17 +29,18 @@
 #include <string>
 #include <map>
 #include <expat.h>
+#include <fstream>
 
 class SAXParser {
 public:
 	SAXParser();
 	virtual ~SAXParser();
 
-	//! Parses the data obtained by readData in chunks.
-	int parse();
+	//! Parses the data from the file.
+	virtual int parseFile(const std::string& filename);
 
 	//! Parses all the data in the buffer.
-	int parse(const std::string& buffer);
+	virtual int parseString(const std::string& str, const std::string& xml_source_name = "");
 
 protected:
 	using attr_t = std::map<std::string, std::string>;
@@ -47,12 +48,11 @@ protected:
 	virtual void characterData(const std::string& data) {}
 	virtual void startTag(const std::string& name, const attr_t& attr) {}
 	virtual void endTag(const std::string& name) {}
-	virtual void parseError(const std::string& buf, std::size_t len, const std::string& error, std::size_t lineno);
-
-	virtual int readData(std::string& data, std::size_t size) { return 0; }
+	virtual void parseError(const std::string& buf, const std::string& error, const std::string& xml_source_name, std::size_t lineno);
 
 private:
 	XML_Parser p;
+	std::string filename;
 
 	static void character_hndl(void* p, const XML_Char* s, int len);
 	static void start_hndl(void* p, const char* el, const char** attr);
-- 
cgit v1.2.3