liblcf
writer_xml.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of liblcf. Copyright (c) 2020 liblcf authors.
3  * https://github.com/EasyRPG/liblcf - https://easyrpg.org
4  *
5  * liblcf is Free/Libre Open Source Software, released under the MIT License.
6  * For the full copyright and license information, please view the COPYING
7  * file that was distributed with this source code.
8  */
9 
10 #include <ostream>
11 #include <vector>
12 #if defined(__amigaos4__) && defined(__NEWLIB__) && defined(__STRICT_ANSI__)
13 #define snprintf(str, size, format, ...) sprintf((str), (format), __VA_ARGS__)
14 #endif
15 
16 #include "writer_xml.h"
17 
18 XmlWriter::XmlWriter(std::ostream& filestream) :
19  stream(filestream),
20  indent(0),
21  at_bol(true)
22 {
23  stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
24 }
25 
26 
28 }
29 
30 template <>
31 void XmlWriter::Write<bool>(const bool& val) {
32  Indent();
33  stream << (val ? "T" : "F");
34 }
35 
36 template <>
37 void XmlWriter::Write<int32_t>(const int32_t& val) {
38  Indent();
39  stream << val;
40 }
41 
42 template <>
43 void XmlWriter::Write<int8_t>(const int8_t& val) {
44  WriteInt((int) val);
45 }
46 
47 template <>
48 void XmlWriter::Write<uint8_t>(const uint8_t& val) {
49  WriteInt((int) val);
50 }
51 
52 template <>
53 void XmlWriter::Write<int16_t>(const int16_t& val) {
54  WriteInt((int) val);
55 }
56 
57 template <>
58 void XmlWriter::Write<uint32_t>(const uint32_t& val) {
59  Indent();
60  stream << val;
61 }
62 
63 template <>
64 void XmlWriter::Write<double>(const double& val) {
65  Indent();
66  stream << val;
67 }
68 
69 template <>
70 void XmlWriter::Write<std::string>(const std::string& val) {
71  Indent();
72  std::string::const_iterator it;
73  for (it = val.begin(); it != val.end(); it++) {
74  int c = (int) *it;
75  switch (c) {
76  case '<':
77  stream << "&lt;";
78  break;
79  case '>':
80  stream << "&gt;";
81  break;
82  case '&':
83  stream << "&amp;";
84  break;
85  case '\n':
86  stream.put(c);
87  at_bol = true;
88  Indent();
89  break;
90  case '\r':
91  case '\t':
92  stream.put(c);
93  break;
94  default:
95  if (c >= 0 && c < 32) {
96  char temp[10];
97  snprintf(temp,10, "&#x%04x;", 0xE000 + c);
98  stream << temp;
99  }
100  else
101  stream.put(c);
102  break;
103  }
104  }
105 }
106 
107 template <>
108 void XmlWriter::Write<std::vector<int32_t>>(const std::vector<int32_t>& val) {
109  WriteVector<int32_t>(val);
110 }
111 
112 template <>
113 void XmlWriter::Write<std::vector<bool>>(const std::vector<bool>& val) {
114  WriteVector<bool>(val);
115 }
116 
117 template <>
118 void XmlWriter::Write<std::vector<uint8_t>>(const std::vector<uint8_t>& val) {
119  WriteVector<uint8_t>(val);
120 }
121 
122 template <>
123 void XmlWriter::Write<std::vector<int16_t>>(const std::vector<int16_t>& val) {
124  WriteVector<int16_t>(val);
125 }
126 
127 template <>
128 void XmlWriter::Write<std::vector<uint32_t>>(const std::vector<uint32_t>& val) {
129  WriteVector<uint32_t>(val);
130 }
131 
132 template <>
133 void XmlWriter::Write<std::vector<double>>(const std::vector<double>& val) {
134  WriteVector<double>(val);
135 }
136 
137 void XmlWriter::WriteInt(int val) {
138  Write<int32_t>(val);
139 }
140 
141 template <class T>
142 void XmlWriter::WriteVector(const std::vector<T>& val) {
143  Indent();
144  typename std::vector<T>::const_iterator it;
145  bool first = true;
146  for (it = val.begin(); it != val.end(); it++) {
147  if (!first)
148  stream.put(' ');
149  first = false;
150  Write<T>(*it);
151  }
152 }
153 
154 template <class T>
155 void XmlWriter::WriteNode(const std::string& name, const T& val) {
156  BeginElement(name);
157  Write<T>(val);
158  EndElement(name);
159 }
160 
161 void XmlWriter::BeginElement(const std::string& name) {
162  NewLine();
163  Indent();
164  stream << "<" << name << ">";
165  indent++;
166 }
167 
168 void XmlWriter::BeginElement(const std::string& name, int ID) {
169  NewLine();
170  Indent();
171  char temp[6];
172  snprintf(temp, 6, "%04d", ID);
173  stream << "<" << name << " id=\"" << temp << "\">";
174  indent++;
175 }
176 
177 void XmlWriter::EndElement(const std::string& name) {
178  indent--;
179  Indent();
180  stream << "</" << name << ">";
181  NewLine();
182 }
183 
185  if (at_bol)
186  return;
187  stream.put('\n');
188  at_bol = true;
189 }
190 
192  if (!at_bol)
193  return;
194  for (int i = 0; i < indent; i++)
195  stream.put(' ');
196  at_bol = false;
197 }
198 
199 bool XmlWriter::IsOk() const {
200  return (stream.good());
201 }
202 
203 template void XmlWriter::WriteNode<bool>(const std::string& name, const bool& val);
204 template void XmlWriter::WriteNode<uint8_t>(const std::string& name, const uint8_t& val);
205 template void XmlWriter::WriteNode<int16_t>(const std::string& name, const int16_t& val);
206 template void XmlWriter::WriteNode<uint32_t>(const std::string& name, const uint32_t& val);
207 template void XmlWriter::WriteNode<int32_t>(const std::string& name, const int32_t& val);
208 template void XmlWriter::WriteNode<double>(const std::string& name, const double& val);
209 template void XmlWriter::WriteNode<std::string>(const std::string& name, const std::string& val);
210 
211 template void XmlWriter::WriteNode<std::vector<bool>>(const std::string& name, const std::vector<bool>& val);
212 template void XmlWriter::WriteNode<std::vector<uint8_t>>(const std::string& name, const std::vector<uint8_t>& val);
213 template void XmlWriter::WriteNode<std::vector<int16_t>>(const std::string& name, const std::vector<int16_t>& val);
214 template void XmlWriter::WriteNode<std::vector<uint32_t>>(const std::string& name, const std::vector<uint32_t>& val);
215 template void XmlWriter::WriteNode<std::vector<int32_t>>(const std::string& name, const std::vector<int32_t>& val);
void WriteInt(int val)
Definition: writer_xml.cpp:137
bool IsOk() const
Definition: writer_xml.cpp:199
bool at_bol
Definition: writer_xml.h:108
void BeginElement(const std::string &name)
Definition: writer_xml.cpp:161
void EndElement(const std::string &name)
Definition: writer_xml.cpp:177
XmlWriter(std::ostream &filestream)
Definition: writer_xml.cpp:18
void NewLine()
Definition: writer_xml.cpp:184
int indent
Definition: writer_xml.h:106
std::ostream & stream
Definition: writer_xml.h:104
void WriteVector(const std::vector< T > &val)
Definition: writer_xml.cpp:142
void WriteNode(const std::string &name, const T &val)
Definition: writer_xml.cpp:155
void Indent()
Definition: writer_xml.cpp:191