1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /***************************************************************************
3  *            configparser.cc
4  *
5  *  Sat Jun 29 21:55:02 CEST 2013
6  *  Copyright 2013 Bent Bisballe Nyeng
7  *  deva@aasimon.org
8  ****************************************************************************/
9 
10 /*
11  *  This file is part of DrumGizmo.
12  *
13  *  DrumGizmo is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU Lesser General Public License as published by
15  *  the Free Software Foundation; either version 3 of the License, or
16  *  (at your option) any later version.
17  *
18  *  DrumGizmo is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU Lesser General Public License for more details.
22  *
23  *  You should have received a copy of the GNU Lesser General Public License
24  *  along with DrumGizmo; if not, write to the Free Software
25  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
26  */
27 #include "configparser.h"
28 
29 #include <hugin.hpp>
30 #include <pugixml.hpp>
31 
assign(std::string & dest,const std::string & val)32 static bool assign(std::string& dest, const std::string& val)
33 {
34 	dest = val;
35 	return true;
36 }
37 
38 template<typename T>
attrcpy(T & dest,const pugi::xml_node & src,const std::string & attr,bool opt=false)39 static bool attrcpy(T& dest, const pugi::xml_node& src, const std::string& attr, bool opt = false)
40 {
41 	const char* val = src.attribute(attr.c_str()).as_string(nullptr);
42 	if(!val)
43 	{
44 		if(!opt)
45 		{
46 			ERR(configparser, "Attribute %s not found in %s, offset %d\n",
47 			    attr.data(), src.path().data(), (int)src.offset_debug());
48 		}
49 		return opt;
50 	}
51 
52 	if(!assign(dest, std::string(val)))
53 	{
54 		ERR(configparser, "Attribute %s could not be assigned, offset %d\n",
55 		    attr.data(), (int)src.offset_debug());
56 		return false;
57 	}
58 
59 	return true;
60 }
61 
parseString(const std::string & xml)62 bool ConfigParser::parseString(const std::string& xml)
63 {
64 	pugi::xml_document doc;
65 	pugi::xml_parse_result result = doc.load_buffer(xml.data(), xml.size());
66 	if(result.status)
67 	{
68 		ERR(configparser, "XML parse error: %d", (int)result.offset);
69 		return false;
70 	}
71 
72 	pugi::xml_node config_node = doc.child("config");
73 
74 	// Config xml without the version tag defaults to 1.0
75 	std::string version = "1.0";
76 	attrcpy(version, config_node, "version", true);
77 	if(version != "1.0")
78 	{
79 		ERR(configparser, "Only config v1.0 XML supported.");
80 		return false;
81 	}
82 
83 	for(pugi::xml_node value_node : config_node.children("value"))
84 	{
85 		auto name = value_node.attribute("name").as_string();
86 		if(std::string(name) == "")
87 		{
88 			continue;
89 		}
90 		auto value = value_node.child_value();
91 		values[name] = value;
92 	}
93 
94 	return true;
95 }
96 
value(const std::string & name,const std::string & def)97 std::string ConfigParser::value(const std::string& name, const std::string& def)
98 {
99 	if(values.find(name) == values.end())
100 	{
101 		return def;
102 	}
103 
104 	return values[name];
105 }
106