adding xml writer
[asdcplib.git] / src / KM_xml.cpp
1 /*
2 Copyright (c) 2005-2006, John Hurst
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 1. Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11    notice, this list of conditions and the following disclaimer in the
12    documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14    derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 /*! \file    KM_xml.cpp
28     \version $Id$
29     \brief   XML writer
30 */
31
32 #include <KM_xml.h>
33
34
35
36 Kumu::XMLElement::XMLElement(const char* name)
37 {
38   m_Name = name;
39 }
40
41 Kumu::XMLElement::~XMLElement()
42 {
43   for ( Elem_i i = m_ChildList.begin(); i != m_ChildList.end(); i++ )
44     delete *i;
45 }
46
47 //
48 void
49 Kumu::XMLElement::SetAttr(const char* name, const char* value)
50 {
51   NVPair TmpVal;
52   TmpVal.name = name;
53   TmpVal.value = value;
54
55   m_AttrList.push_back(TmpVal);
56 }
57
58 //
59 Kumu::XMLElement*
60 Kumu::XMLElement::AddChild(const char* name)
61 {
62   XMLElement* tmpE = new XMLElement(name);
63   m_ChildList.push_back(tmpE);
64   return tmpE;
65 }
66
67 //
68 Kumu::XMLElement*
69 Kumu::XMLElement::AddChildWithContent(const char* name, const std::string& value)
70 {
71   return AddChildWithContent(name, value.c_str());
72 }
73
74 //
75 Kumu::XMLElement*
76 Kumu::XMLElement::AddChildWithContent(const char* name, const char* value)
77 {
78   assert(name);
79   assert(value);
80   XMLElement* tmpE = new XMLElement(name);
81   tmpE->m_Body = value;
82   m_ChildList.push_back(tmpE);
83   return tmpE;
84 }
85
86 //
87 Kumu::XMLElement*
88 Kumu::XMLElement::AddChildWithPrefixedContent(const char* name, const char* prefix, const char* value)
89 {
90   XMLElement* tmpE = new XMLElement(name);
91   tmpE->m_Body = prefix;
92   tmpE->m_Body += value;
93   m_ChildList.push_back(tmpE);
94   return tmpE;
95 }
96
97 //
98 void
99 Kumu::XMLElement::AddComment(const char* value)
100 {
101   m_Body += "  <!-- ";
102   m_Body += value;
103   m_Body += " -->\n";
104 }
105
106 //
107 void
108 Kumu::XMLElement::Render(std::string& outbuf)
109 {
110   outbuf = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
111   RenderElement(outbuf, 0);
112 }
113
114 //
115 inline void
116 add_spacer(std::string& outbuf, i32_t depth)
117 {
118   while ( depth-- )
119     outbuf+= "  ";
120 }
121
122 //
123 void
124 Kumu::XMLElement::RenderElement(std::string& outbuf, ui32_t depth)
125 {
126   add_spacer(outbuf, depth);
127
128   outbuf += "<";
129   outbuf += m_Name;
130
131   // render attributes
132   for ( Attr_i i = m_AttrList.begin(); i != m_AttrList.end(); i++ )
133     {
134       outbuf += " ";
135       outbuf += (*i).name;
136       outbuf += "=\"";
137       outbuf += (*i).value;
138       outbuf += "\"";
139     }
140
141   // body contents and children
142   if ( ! m_ChildList.empty() )
143     {
144       outbuf += ">\n";
145
146       // render body
147       if ( m_Body.length() > 0 )
148         outbuf += m_Body;
149
150       for ( Elem_i i = m_ChildList.begin(); i != m_ChildList.end(); i++ )
151         (*i)->RenderElement(outbuf, depth + 1);
152
153       add_spacer(outbuf, depth);
154       outbuf += "</";
155       outbuf += m_Name;
156       outbuf += ">\n";
157     }
158   else if ( m_Body.length() > 0 )
159     {
160       outbuf += ">";
161       outbuf += m_Body;
162       outbuf += "</";
163       outbuf += m_Name;
164       outbuf += ">\n";
165     }
166   else
167     {
168       outbuf += " />\n";
169     }
170 }
171
172
173 //
174 // end KM_xml.cpp
175 //