Mercurial > minori
annotate dep/pugixml/docs/samples/save_custom_writer.cpp @ 187:9613d72b097e
*: multiple performance improvements
like marking `static const` when it makes sense...
date: change old stupid heap-based method to a structure which should
make copying the thing actually make a copy.
also many performance-based changes, like removing the std::tie
dependency and forward-declaring nlohmann json
*: replace every instance of QString::fromUtf8 to Strings::ToQString.
the main difference is that our function will always convert exactly
what is in the string, while some other times it would only convert
up to the nearest NUL byte
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Wed, 06 Dec 2023 13:43:54 -0500 |
parents | d10b6c6b432e |
children |
rev | line source |
---|---|
55
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
1 #include "pugixml.hpp" |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
2 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
3 #include <string> |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
4 #include <iostream> |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
5 #include <cstring> |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
6 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
7 // tag::code[] |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
8 struct xml_string_writer: pugi::xml_writer |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
9 { |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
10 std::string result; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
11 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
12 virtual void write(const void* data, size_t size) |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
13 { |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
14 result.append(static_cast<const char*>(data), size); |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
15 } |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
16 }; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
17 // end::code[] |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
18 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
19 struct xml_memory_writer: pugi::xml_writer |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
20 { |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
21 char* buffer; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
22 size_t capacity; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
23 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
24 size_t result; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
25 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
26 xml_memory_writer(): buffer(0), capacity(0), result(0) |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
27 { |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
28 } |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
29 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
30 xml_memory_writer(char* buffer, size_t capacity): buffer(buffer), capacity(capacity), result(0) |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
31 { |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
32 } |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
33 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
34 size_t written_size() const |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
35 { |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
36 return result < capacity ? result : capacity; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
37 } |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
38 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
39 virtual void write(const void* data, size_t size) |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
40 { |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
41 if (result < capacity) |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
42 { |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
43 size_t chunk = (capacity - result < size) ? capacity - result : size; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
44 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
45 memcpy(buffer + result, data, chunk); |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
46 } |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
47 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
48 result += size; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
49 } |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
50 }; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
51 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
52 std::string node_to_string(pugi::xml_node node) |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
53 { |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
54 xml_string_writer writer; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
55 node.print(writer); |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
56 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
57 return writer.result; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
58 } |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
59 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
60 char* node_to_buffer(pugi::xml_node node, char* buffer, size_t size) |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
61 { |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
62 if (size == 0) return buffer; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
63 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
64 // leave one character for null terminator |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
65 xml_memory_writer writer(buffer, size - 1); |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
66 node.print(writer); |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
67 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
68 // null terminate |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
69 buffer[writer.written_size()] = 0; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
70 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
71 return buffer; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
72 } |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
73 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
74 char* node_to_buffer_heap(pugi::xml_node node) |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
75 { |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
76 // first pass: get required memory size |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
77 xml_memory_writer counter; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
78 node.print(counter); |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
79 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
80 // allocate necessary size (+1 for null termination) |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
81 char* buffer = new char[counter.result + 1]; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
82 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
83 // second pass: actual printing |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
84 xml_memory_writer writer(buffer, counter.result); |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
85 node.print(writer); |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
86 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
87 // null terminate |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
88 buffer[writer.written_size()] = 0; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
89 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
90 return buffer; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
91 } |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
92 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
93 int main() |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
94 { |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
95 // get a test document |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
96 pugi::xml_document doc; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
97 doc.load_string("<foo bar='baz'>hey</foo>"); |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
98 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
99 // get contents as std::string (single pass) |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
100 std::cout << "contents: [" << node_to_string(doc) << "]\n"; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
101 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
102 // get contents into fixed-size buffer (single pass) |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
103 char large_buf[128]; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
104 std::cout << "contents: [" << node_to_buffer(doc, large_buf, sizeof(large_buf)) << "]\n"; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
105 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
106 // get contents into fixed-size buffer (single pass, shows truncating behavior) |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
107 char small_buf[22]; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
108 std::cout << "contents: [" << node_to_buffer(doc, small_buf, sizeof(small_buf)) << "]\n"; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
109 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
110 // get contents into heap-allocated buffer (two passes) |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
111 char* heap_buf = node_to_buffer_heap(doc); |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
112 std::cout << "contents: [" << heap_buf << "]\n"; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
113 delete[] heap_buf; |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
114 } |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
115 |
d10b6c6b432e
add xml lib, we will need to use it eventually
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
116 // vim:et |