1 // Libiqxmlrpc - an object-oriented XML-RPC solution.
2 // Copyright (C) 2011 Anton Dedov
3
4 #include <stdexcept>
5 #include "except.h"
6 #include "xml_builder.h"
7
8 namespace iqxmlrpc {
9
10 namespace {
11
12 template <class T>
13 void
throwBuildError(T res,T err_res)14 throwBuildError(T res, T err_res)
15 {
16 if (res == err_res) {
17 xmlErrorPtr err = xmlGetLastError();
18 throw XmlBuild_error(err ? err->message : "unknown error");
19 }
20 }
21
22 } // anonymous namespace
23
24 //
25 // XmlBuilder::Node
26 //
27
Node(XmlBuilder & w,const char * name)28 XmlBuilder::Node::Node(XmlBuilder& w, const char* name):
29 ctx(w)
30 {
31 const xmlChar* xname = reinterpret_cast<const xmlChar*>(name);
32 throwBuildError(xmlTextWriterStartElement(ctx.writer, xname), -1);
33 }
34
~Node()35 XmlBuilder::Node::~Node()
36 {
37 xmlTextWriterEndElement(ctx.writer);
38 }
39
40 void
set_textdata(const std::string & data)41 XmlBuilder::Node::set_textdata(const std::string& data)
42 {
43 ctx.add_textdata(data);
44 }
45
46 //
47 // XmlBuilder
48 //
49
XmlBuilder()50 XmlBuilder::XmlBuilder()
51 {
52 buf = xmlBufferCreate();
53 throwBuildError(writer = xmlNewTextWriterMemory(buf, 0), (xmlTextWriter*)0);
54 throwBuildError(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL), -1);
55 }
56
~XmlBuilder()57 XmlBuilder::~XmlBuilder()
58 {
59 xmlFreeTextWriter(writer);
60 xmlBufferFree(buf);
61 }
62
63 void
add_textdata(const std::string & data)64 XmlBuilder::add_textdata(const std::string& data)
65 {
66 const xmlChar* xdata = reinterpret_cast<const xmlChar*>(data.c_str());
67 throwBuildError(xmlTextWriterWriteString(writer, xdata), -1);
68 }
69
70 void
stop()71 XmlBuilder::stop()
72 {
73 throwBuildError(xmlTextWriterEndDocument(writer), -1);
74 }
75
76 std::string
content() const77 XmlBuilder::content() const
78 {
79 xmlTextWriterFlush(writer);
80 const char* cdata = reinterpret_cast<const char*>(xmlBufferContent(buf));
81 return std::string(cdata, buf->use);
82 }
83
84 } // namespace iqxmlrpc
85 // vim:ts=2:sw=2:et
86