blob: 6d0ecf607457440b492c3c8315932b0a29790e39 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
#include "rapidxml.hpp"
#include <cstddef>
#include <cstring>
namespace rx = rapidxml;
inline bool is_highway_crossing(rx::xml_node<>* tag_node) {
rx::xml_attribute<>* k = tag_node->first_attribute();
if (!k) return false;
rx::xml_attribute<>* v = k->next_attribute();
if (!v) return false;
return std::strcmp(k->value(), "highway") == 0 &&
std::strcmp(v->value(), "crossing") == 0;
}
size_t count_highway_crossings(char* buffer, size_t len) {
rx::xml_document<> doc;
try {
doc.parse<rx::parse_no_data_nodes | rx::parse_no_element_values>(buffer);
} catch (const rx::parse_error&) {
return 0;
}
size_t count = 0;
rx::xml_node<>* osm = doc.first_node("osm");
if (!osm)
return count;
for (rx::xml_node<>* node = osm->first_node("node");
node;
node = node->next_sibling("node")) {
for (rx::xml_node<>* tag = node->first_node("tag");
tag;
tag = tag->next_sibling("tag")) {
if (is_highway_crossing(tag))
++count;
}
}
return count;
}
size_t count_highway_crossings_cheat_and_early_out(char* buffer, size_t len) {
rx::xml_document<> doc;
try {
doc.parse<rx::parse_no_data_nodes | rx::parse_no_element_values>(buffer);
} catch (const rx::parse_error&) {
return 0;
}
size_t count = 0;
rx::xml_node<>* osm = doc.first_node("osm");
if (!osm)
return count;
// Equivalent to iterating over all children and stopping at "way".
// next_sibling() avoids inspecting unrelated nodes between elements.
for (rx::xml_node<>* top = osm->first_node();
top;
top = top->next_sibling()) {
if (std::strcmp(top->name(), "way") == 0)
break;
for (rx::xml_node<>* tag = top->first_node("tag");
tag;
tag = tag->next_sibling("tag")) {
if (is_highway_crossing(tag))
++count;
}
}
return count;
}
|