summaryrefslogtreecommitdiff
path: root/benchmarks/RapidXML/pubmed_len.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'benchmarks/RapidXML/pubmed_len.cpp')
-rw-r--r--benchmarks/RapidXML/pubmed_len.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/benchmarks/RapidXML/pubmed_len.cpp b/benchmarks/RapidXML/pubmed_len.cpp
new file mode 100644
index 0000000..f25f33b
--- /dev/null
+++ b/benchmarks/RapidXML/pubmed_len.cpp
@@ -0,0 +1,46 @@
+#include "rapidxml.hpp"
+#include <cstring>
+
+inline bool is_content_root(const char* name, std::size_t len) {
+ return (len == 8 && std::memcmp(name, "abstract", 8) == 0) ||
+ (len == 4 && std::memcmp(name, "body", 4) == 0);
+}
+
+size_t sum_text(const rapidxml::xml_node<>* node) {
+ size_t total = 0;
+ for (auto* child = node->first_node(); child; child = child->next_sibling()) {
+ if (child->type() == rapidxml::node_type::node_data) {
+ total += child->value_size();
+ } else if (child->type() == rapidxml::node_type::node_element) {
+ total += sum_text(child);
+ }
+ }
+ return total;
+}
+
+size_t walk(const rapidxml::xml_node<>* node) {
+ size_t total = 0;
+ for (auto* child = node->first_node(); child; child = child->next_sibling()) {
+ if (child->type() != rapidxml::node_type::node_element) continue;
+ if (is_content_root(child->name(), child->name_size())) {
+ total += sum_text(child);
+ } else {
+ total += walk(child);
+ }
+ }
+ return total;
+}
+
+size_t pubmed_len(char* buffer, size_t /*len*/) {
+ rapidxml::xml_document<> doc;
+ doc.parse<rapidxml::parse_no_entity_translation |
+ rapidxml::parse_no_string_terminators>(buffer);
+ return walk(&doc);
+}
+
+size_t pubmed_len_with_entities(char* buffer, size_t /*len*/) {
+ rapidxml::xml_document<> doc;
+ doc.parse<rapidxml::parse_no_string_terminators>(buffer);
+ return walk(&doc);
+}
+