Subversion Repositories HomeAutomation

Rev

Rev 997 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

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