source: subversion/applications/lib/libosm/Parser.cpp @ 34963

Last change on this file since 34963 was 17744, checked in by nienhueser, 10 years ago

Verbose error message on parsing errors. Make sure error string is reset it parsing succeeds.

File size: 3.0 KB
Line 
1#include "Parser.h"
2#include "Node.h"
3#include "Way.h"
4#include "Components.h"
5#include <string>
6#include <cstring>
7#include <sstream>
8
9using std::cerr;
10using std::endl;
11
12namespace OSM
13{
14
15Object* Parser::curObject = NULL;
16int Parser::curID = 0;
17bool Parser::inNode = false, Parser::inWay = false;
18Components* Parser::components = NULL;
19std::string Parser::error = "";
20
21std::string Parser::getError()
22{
23        return error;
24}
25
26void Parser::startElement(void *d, const XML_Char* element,
27                const XML_Char** attrs)
28{
29        double lat, lon;
30        std::string tags;
31
32        if (!strcmp(element, "node"))
33        {
34                curID = 0;
35                inNode = true;
36                int count = 0;
37                while (attrs[count])
38                {
39                        if (!strcmp(attrs[count], "lat"))
40                                lat = atof(attrs[count + 1]);
41                        if (!strcmp(attrs[count], "lon"))
42                                lon = atof(attrs[count + 1]);
43                        if (!strcmp(attrs[count], "id"))
44                                curID = atoi(attrs[count + 1]);
45                        count += 2;
46                }
47
48                curObject = new Node(curID, lat, lon);
49                components->addNode((Node*) curObject);
50
51        }
52        else if (!strcmp(element, "way"))
53        {
54                curID = 0;
55                inWay = true;
56                for (int count = 0; attrs[count]; count += 2)
57                {
58                        if (!strcmp(attrs[count], "id"))
59                                curID = atoi(attrs[count + 1]);
60                }
61                curObject = new Way(curID);
62                components->addWay((Way*) curObject);
63        }
64        else if (!strcmp(element, "nd") && (inWay))
65        {
66                int nodeID;
67
68                for (int count = 0; attrs[count]; count += 2)
69                {
70                        if (!strcmp(attrs[count], "ref"))
71                        {
72                                nodeID = atoi(attrs[count + 1]);
73                                ((Way*) curObject)->addNode(nodeID);
74                        }
75                }
76
77        }
78        else if (!strcmp(element, "tag"))
79        {
80                std::string key = "", value = "";
81
82                for (int count = 0; attrs[count]; count += 2)
83                {
84                        if (!strcmp(attrs[count], "k"))
85                                key = attrs[count + 1];
86                        if (!strcmp(attrs[count], "v"))
87                                value = attrs[count + 1];
88                }
89
90                curObject->addTag(key, value);
91        }
92}
93
94void Parser::endElement(void *d, const XML_Char* element)
95{
96        if (!strcmp(element, "node"))
97        {
98                inNode = false;
99        }
100        else if (!strcmp(element, "way"))
101        {
102                inWay = false;
103        }
104}
105
106void Parser::characters(void*, const XML_Char* txt, int txtlen)
107{
108}
109
110Components* Parser::parse(std::istream &in)
111{
112        int done, count = 0, n;
113        char buf[4096];
114
115        XML_Parser p = XML_ParserCreate(NULL);
116        if (!p)
117        {
118                error = "Error creating parser";
119                return NULL;
120        }
121
122        XML_SetElementHandler(p, Parser::startElement, Parser::endElement);
123        XML_SetCharacterDataHandler(p, Parser::characters);
124        components = new Components;
125
126        // straight from example
127        do
128        {
129                in.read(buf, 4096);
130                n = in.gcount();
131                done = (n != 4096);
132                if (XML_Parse(p, buf, n, done) == XML_STATUS_ERROR)
133                {
134                        XML_Error errorCode = XML_GetErrorCode(p);
135                        int errorLine = XML_GetCurrentLineNumber(p);
136                        long errorCol = XML_GetCurrentColumnNumber(p);
137                        const XML_LChar *errorString = XML_ErrorString(errorCode);
138                        std::stringstream errorDesc;
139                        errorDesc << "XML parsing error at line " << errorLine << ":" << errorCol;
140                        errorDesc << ": " << errorString;
141                        error = errorDesc.str();
142                        delete components;
143                        return NULL;
144                }
145                count += n;
146        } while (!done);
147
148        XML_ParserFree(p);
149        error = "";
150        return components;
151}
152
153}
Note: See TracBrowser for help on using the repository browser.