2006/06/23 tmccolm
[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   outbuf += ">";
142
143   // body contents and children
144   if ( ! m_ChildList.empty() )
145     {
146       outbuf += "\n";
147
148       // render body
149       if ( m_Body.length() > 0 )
150         outbuf += m_Body;
151
152       for ( Elem_i i = m_ChildList.begin(); i != m_ChildList.end(); i++ )
153         (*i)->RenderElement(outbuf, depth + 1);
154
155       add_spacer(outbuf, depth);
156     }
157   else if ( m_Body.length() > 0 )
158     {
159       outbuf += m_Body;
160     }
161
162   outbuf += "</";
163   outbuf += m_Name;
164   outbuf += ">\n";
165 }
166
167
168 //
169 // end KM_xml.cpp
170 //