comparison dep/pugixml/docs/samples/save_custom_writer.cpp @ 55:d10b6c6b432e

add xml lib, we will need to use it eventually
author Paper <mrpapersonic@gmail.com>
date Tue, 26 Sep 2023 12:37:08 -0400
parents
children
comparison
equal deleted inserted replaced
54:466ac9870df9 55:d10b6c6b432e
1 #include "pugixml.hpp"
2
3 #include <string>
4 #include <iostream>
5 #include <cstring>
6
7 // tag::code[]
8 struct xml_string_writer: pugi::xml_writer
9 {
10 std::string result;
11
12 virtual void write(const void* data, size_t size)
13 {
14 result.append(static_cast<const char*>(data), size);
15 }
16 };
17 // end::code[]
18
19 struct xml_memory_writer: pugi::xml_writer
20 {
21 char* buffer;
22 size_t capacity;
23
24 size_t result;
25
26 xml_memory_writer(): buffer(0), capacity(0), result(0)
27 {
28 }
29
30 xml_memory_writer(char* buffer, size_t capacity): buffer(buffer), capacity(capacity), result(0)
31 {
32 }
33
34 size_t written_size() const
35 {
36 return result < capacity ? result : capacity;
37 }
38
39 virtual void write(const void* data, size_t size)
40 {
41 if (result < capacity)
42 {
43 size_t chunk = (capacity - result < size) ? capacity - result : size;
44
45 memcpy(buffer + result, data, chunk);
46 }
47
48 result += size;
49 }
50 };
51
52 std::string node_to_string(pugi::xml_node node)
53 {
54 xml_string_writer writer;
55 node.print(writer);
56
57 return writer.result;
58 }
59
60 char* node_to_buffer(pugi::xml_node node, char* buffer, size_t size)
61 {
62 if (size == 0) return buffer;
63
64 // leave one character for null terminator
65 xml_memory_writer writer(buffer, size - 1);
66 node.print(writer);
67
68 // null terminate
69 buffer[writer.written_size()] = 0;
70
71 return buffer;
72 }
73
74 char* node_to_buffer_heap(pugi::xml_node node)
75 {
76 // first pass: get required memory size
77 xml_memory_writer counter;
78 node.print(counter);
79
80 // allocate necessary size (+1 for null termination)
81 char* buffer = new char[counter.result + 1];
82
83 // second pass: actual printing
84 xml_memory_writer writer(buffer, counter.result);
85 node.print(writer);
86
87 // null terminate
88 buffer[writer.written_size()] = 0;
89
90 return buffer;
91 }
92
93 int main()
94 {
95 // get a test document
96 pugi::xml_document doc;
97 doc.load_string("<foo bar='baz'>hey</foo>");
98
99 // get contents as std::string (single pass)
100 std::cout << "contents: [" << node_to_string(doc) << "]\n";
101
102 // get contents into fixed-size buffer (single pass)
103 char large_buf[128];
104 std::cout << "contents: [" << node_to_buffer(doc, large_buf, sizeof(large_buf)) << "]\n";
105
106 // get contents into fixed-size buffer (single pass, shows truncating behavior)
107 char small_buf[22];
108 std::cout << "contents: [" << node_to_buffer(doc, small_buf, sizeof(small_buf)) << "]\n";
109
110 // get contents into heap-allocated buffer (two passes)
111 char* heap_buf = node_to_buffer_heap(doc);
112 std::cout << "contents: [" << heap_buf << "]\n";
113 delete[] heap_buf;
114 }
115
116 // vim:et