Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
969 runge 1
/***************************************************************************
2
 *   Copyright (C) November 30, 2008 by Mattias Runge                             *
3
 *   mattias@runge.se                                                      *
4
 *   xmlnode.cpp                                            *
5
 *                                                                         *
6
 *   This program is free software; you can redistribute it and/or modify  *
7
 *   it under the terms of the GNU General Public License as published by  *
8
 *   the Free Software Foundation; either version 2 of the License, or     *
9
 *   (at your option) any later version.                                   *
10
 *                                                                         *
11
 *   This program is distributed in the hope that it will be useful,       *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU General Public License for more details.                          *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU General Public License     *
17
 *   along with this program; if not, write to the                         *
18
 *   Free Software Foundation, Inc.,                                       *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20
 ***************************************************************************/
21
 
22
#include "xmlnode.h"
23
 
24
void XmlNode::load(string filename)
25
{
26
	parse(file_get_contents(filename));
27
}
28
 
29
void XmlNode::parse(string xmlData)
30
{
31
	char c;
32
	int position = 0;
33
	while (position < xmlData.length())
34
	{
35
		c = xmlData.at(position);
36
 
37
		switch (c)
38
		{
39
			case '<':
40
				position = parseTag(xmlData, position);
41
				break;
42
		}
43
		position++;
44
	}
45
}
46
 
47
int XmlNode::parseTag(string xmlData, int position)
48
{
49
	if (xmlData.at(position) != '<')
50
		throw new XmlException("Did not find < as expected. Character " + itos(position));
51
 
52
	position++;
53
 
54
	int endPosition = xmlData.find('>', position);
55
 
56
	if (xmlData.at(position) == '?' || xmlData.at(position) == '!' || xmlData.at(position) == '/')
57
	{
58
		return endPosition;
59
	}
60
 
997 runge 61
	string tagString;
969 runge 62
 
997 runge 63
	try
64
	{
65
		tagString = xmlData.substr(position, endPosition-position);
66
	}
67
	catch (std::out_of_range& e)
68
	{
69
		cout << "DEBUG: parseTag exception: " << e.what() << "\n";
70
		cout << "DEBUG: A xmlData=" << xmlData << " :: position=" << position << " :: endPosition=" << endPosition << endl;
71
	}
72
 
969 runge 73
	tagString = trim(tagString);
74
	tagString = trim(tagString, '\n');
75
	tagString = trim(tagString);
76
	tagString += " ";
77
 
78
	bool foundEnd = false;
79
	bool foundTag = false;
80
	string buffer;
81
	int pos = 0;
82
	char c;
83
	int s, e;
84
 
85
	while (pos < tagString.length())
86
	{
87
		c = tagString.at(pos);
88
 
89
		switch (c)
90
		{
91
			case ' ':
92
				if (!foundTag)
93
				{
94
					myTagName = buffer;
95
					buffer = "";
96
					//cout << "Found tag: " << myTagName << endl;
97
					foundTag = true;
98
				}
99
				break;
100
 
101
			case '/':
102
				foundEnd = true;
103
				break;
104
 
105
			case '=':
106
				s = tagString.find('"', pos)+1;
107
				e = tagString.find('"', s);
108
 
997 runge 109
				try
110
				{
111
					myAttributes[buffer] = tagString.substr(s, e-s);
112
				}
113
				catch (std::out_of_range& ex)
114
				{
115
					cout << "DEBUG: parseTag exception: " << ex.what() << "\n";
116
					cout << "DEBUG: B tagString=" << tagString << " :: s=" << s << " :: e=" << e << endl;
117
					continue;
118
				}
119
 
120
 
969 runge 121
				//cout << "Found attribute: " << buffer << " = " << myAttributes[buffer] << endl;
122
				pos = e;
123
				buffer = "";
124
				break;
125
 
126
			default:
127
				buffer += c;
128
				break;
129
		}
130
		pos++;
131
	}
132
 
133
	position = endPosition;
134
 
135
	if (!foundEnd)
136
	{
137
		while (position < xmlData.length())
138
		{
139
			c = xmlData.at(position);
140
 
141
			switch (c)
142
			{
143
				case '<':
144
					if (xmlData.at(position+1) == '/')
145
					{
146
						position += 2;
147
						endPosition = xmlData.find('>', position);
148
 
997 runge 149
						try
969 runge 150
						{
997 runge 151
							if (myTagName.compare(xmlData.substr(position, endPosition-position)) == 0)
152
							{
153
								//cout << "Found end tag: " << myTagName << endl;
154
								return endPosition;
155
							}
156
							else
157
							{
158
								throw new XmlException("Invalid end tag found. " + xmlData.substr(position, endPosition-position) + "::" + myTagName);
159
							}
969 runge 160
						}
997 runge 161
						catch (std::out_of_range& e)
969 runge 162
						{
997 runge 163
							cout << "DEBUG: parseTag exception: " << e.what() << "\n";
164
							cout << "DEBUG: C xmlData=" << xmlData << " :: position=" << position << " :: endPosition=" << endPosition << endl;
165
							continue;
969 runge 166
						}
997 runge 167
 
168
 
969 runge 169
					}
170
 
171
					XmlNode subNode;
172
					position = subNode.parseTag(xmlData, position);
173
					myChildren.push_back(subNode);
174
					break;
175
			}
176
 
177
			position++;
178
		}
179
	}
180
 
181
	return position;
182
}
183
 
184
XmlNode XmlNode::findChild(string tagName)
185
{
186
	for (int n = 0; n < myChildren.size(); n++)
187
	{
188
		if (myChildren[n].getTagName().compare(tagName) == 0)
189
			return myChildren[n];
190
	}
191
 
192
	XmlNode defaultNode;
193
 
194
	return defaultNode;
195
}
196
 
197
string XmlNode::getAttributeValue(string attributeName)
198
{
199
	map<string, string>::const_iterator iterator = myAttributes.find(attributeName);
200
 
201
	if (iterator == myAttributes.end())
202
		return NULL;
203
 
204
	return iterator->second;
205
}