From 65e90b2d7a86383243e380b2658fad26dce370f0 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 8 Apr 2015 21:44:16 -0700 Subject: docs: Add docs folder from master --- docs/samples/save_custom_writer.cpp | 116 ++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 docs/samples/save_custom_writer.cpp (limited to 'docs/samples/save_custom_writer.cpp') diff --git a/docs/samples/save_custom_writer.cpp b/docs/samples/save_custom_writer.cpp new file mode 100644 index 0000000..e777a32 --- /dev/null +++ b/docs/samples/save_custom_writer.cpp @@ -0,0 +1,116 @@ +#include "pugixml.hpp" + +#include +#include +#include + +// tag::code[] +struct xml_string_writer: pugi::xml_writer +{ + std::string result; + + virtual void write(const void* data, size_t size) + { + result.append(static_cast(data), size); + } +}; +// end::code[] + +struct xml_memory_writer: pugi::xml_writer +{ + char* buffer; + size_t capacity; + + size_t result; + + xml_memory_writer(): buffer(0), capacity(0), result(0) + { + } + + xml_memory_writer(char* buffer, size_t capacity): buffer(buffer), capacity(capacity), result(0) + { + } + + size_t written_size() const + { + return result < capacity ? result : capacity; + } + + virtual void write(const void* data, size_t size) + { + if (result < capacity) + { + size_t chunk = (capacity - result < size) ? capacity - result : size; + + memcpy(buffer + result, data, chunk); + } + + result += size; + } +}; + +std::string node_to_string(pugi::xml_node node) +{ + xml_string_writer writer; + node.print(writer); + + return writer.result; +} + +char* node_to_buffer(pugi::xml_node node, char* buffer, size_t size) +{ + if (size == 0) return buffer; + + // leave one character for null terminator + xml_memory_writer writer(buffer, size - 1); + node.print(writer); + + // null terminate + buffer[writer.written_size()] = 0; + + return buffer; +} + +char* node_to_buffer_heap(pugi::xml_node node) +{ + // first pass: get required memory size + xml_memory_writer counter; + node.print(counter); + + // allocate necessary size (+1 for null termination) + char* buffer = new char[counter.result + 1]; + + // second pass: actual printing + xml_memory_writer writer(buffer, counter.result); + node.print(writer); + + // null terminate + buffer[writer.written_size()] = 0; + + return buffer; +} + +int main() +{ + // get a test document + pugi::xml_document doc; + doc.load_string("hey"); + + // get contents as std::string (single pass) + std::cout << "contents: [" << node_to_string(doc) << "]\n"; + + // get contents into fixed-size buffer (single pass) + char large_buf[128]; + std::cout << "contents: [" << node_to_buffer(doc, large_buf, sizeof(large_buf)) << "]\n"; + + // get contents into fixed-size buffer (single pass, shows truncating behavior) + char small_buf[22]; + std::cout << "contents: [" << node_to_buffer(doc, small_buf, sizeof(small_buf)) << "]\n"; + + // get contents into heap-allocated buffer (two passes) + char* heap_buf = node_to_buffer_heap(doc); + std::cout << "contents: [" << heap_buf << "]\n"; + delete[] heap_buf; +} + +// vim:et -- cgit v1.2.3