liblcf
writer_xml.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of liblcf. Copyright (c) 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 
13 #include "lcf/saveopt.h"
14 #include "lcf/writer_xml.h"
15 #include "lcf/dbstring.h"
16 #include "lcf/dbarray.h"
17 #include "lcf/dbbitarray.h"
18 
19 namespace lcf {
20 
21 XmlWriter::XmlWriter(std::ostream& filestream, EngineVersion engine) :
22  stream(filestream),
23  indent(0),
24  at_bol(true),
25  engine(engine)
26 {
27  stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
28 }
29 
30 
31 XmlWriter::~XmlWriter() {
32 }
33 
34 template <>
35 void XmlWriter::Write<bool>(const bool& val) {
36  Indent();
37  stream << (val ? "T" : "F");
38 }
39 
40 template <>
41 void XmlWriter::Write<int32_t>(const int32_t& val) {
42  Indent();
43  stream << val;
44 }
45 
46 template <>
47 void XmlWriter::Write<int8_t>(const int8_t& val) {
48  WriteInt((int) val);
49 }
50 
51 template <>
52 void XmlWriter::Write<uint8_t>(const uint8_t& val) {
53  WriteInt((int) val);
54 }
55 
56 template <>
57 void XmlWriter::Write<int16_t>(const int16_t& val) {
58  WriteInt((int) val);
59 }
60 
61 template <>
62 void XmlWriter::Write<uint32_t>(const uint32_t& val) {
63  Indent();
64  stream << val;
65 }
66 
67 template <>
68 void XmlWriter::Write<double>(const double& val) {
69  Indent();
70  stream << val;
71 }
72 
73 void XmlWriter::WriteString(StringView val) {
74  Indent();
75  for (auto c: val) {
76  switch (c) {
77  case '<':
78  stream << "&lt;";
79  break;
80  case '>':
81  stream << "&gt;";
82  break;
83  case '&':
84  stream << "&amp;";
85  break;
86  case '\n':
87  stream.put(c);
88  break;
89  case '\r':
90  case '\t':
91  stream.put(c);
92  break;
93  default:
94  if (c >= 0 && c < 32) {
95  char temp[10];
96  snprintf(temp,10, "&#x%04x;", 0xE000 + c);
97  stream << temp;
98  }
99  else
100  stream.put(c);
101  break;
102  }
103  }
104 }
105 
106 template <>
107 void XmlWriter::Write<std::string>(const std::string& val) {
108  WriteString(val);
109 }
110 
111 template <>
112 void XmlWriter::Write<DBString>(const DBString& val) {
113  WriteString(val);
114 }
115 
116 template <>
117 void XmlWriter::Write<std::vector<int32_t>>(const std::vector<int32_t>& val) {
118  WriteVector(val);
119 }
120 
121 template <>
122 void XmlWriter::Write<std::vector<bool>>(const std::vector<bool>& val) {
123  WriteVector(val);
124 }
125 
126 template <>
127 void XmlWriter::Write<std::vector<uint8_t>>(const std::vector<uint8_t>& val) {
128  WriteVector(val);
129 }
130 
131 template <>
132 void XmlWriter::Write<std::vector<int16_t>>(const std::vector<int16_t>& val) {
133  WriteVector(val);
134 }
135 
136 template <>
137 void XmlWriter::Write<std::vector<uint32_t>>(const std::vector<uint32_t>& val) {
138  WriteVector(val);
139 }
140 
141 template <>
142 void XmlWriter::Write<std::vector<double>>(const std::vector<double>& val) {
143  WriteVector(val);
144 }
145 
146 template <>
147 void XmlWriter::Write<DBArray<int32_t>>(const DBArray<int32_t>& val) {
148  WriteVector(val);
149 }
150 
151 template <>
152 void XmlWriter::Write<DBArray<bool>>(const DBArray<bool>& val) {
153  WriteVector(val);
154 }
155 
156 template <>
157 void XmlWriter::Write<DBArray<uint8_t>>(const DBArray<uint8_t>& val) {
158  WriteVector(val);
159 }
160 
161 template <>
162 void XmlWriter::Write<DBArray<int16_t>>(const DBArray<int16_t>& val) {
163  WriteVector(val);
164 }
165 
166 template <>
167 void XmlWriter::Write<DBArray<uint32_t>>(const DBArray<uint32_t>& val) {
168  WriteVector(val);
169 }
170 
171 template <>
172 void XmlWriter::Write<DBArray<double>>(const DBArray<double>& val) {
173  WriteVector(val);
174 }
175 
176 void XmlWriter::WriteInt(int val) {
177  Write<int32_t>(val);
178 }
179 
180 template <>
181 void XmlWriter::Write(const DBBitArray& val) {
182  WriteVector(val);
183 }
184 
185 template <typename ArrayType>
186 void XmlWriter::WriteVector(const ArrayType& val) {
187  Indent();
188  bool first = true;
189  for (auto&& e: val) {
190  if (!first)
191  stream.put(' ');
192  first = false;
193  Write<typename ArrayType::value_type>(e);
194  }
195 }
196 
197 template <class T>
198 void XmlWriter::WriteNode(const std::string& name, const T& val) {
199  BeginElement(name);
200  Write<T>(val);
201  EndElement(name);
202 }
203 
204 void XmlWriter::BeginElement(const std::string& name) {
205  NewLine();
206  Indent();
207  stream << "<" << name << ">";
208  indent++;
209 }
210 
211 void XmlWriter::BeginElement(const std::string& name, int ID) {
212  NewLine();
213  Indent();
214  char temp[6];
215  snprintf(temp, 6, "%04d", ID);
216  stream << "<" << name << " id=\"" << temp << "\">";
217  indent++;
218 }
219 
220 void XmlWriter::EndElement(const std::string& name) {
221  indent--;
222  Indent();
223  stream << "</" << name << ">";
224  NewLine();
225 }
226 
227 void XmlWriter::NewLine() {
228  if (at_bol)
229  return;
230  stream.put('\n');
231  at_bol = true;
232 }
233 
234 void XmlWriter::Indent() {
235  if (!at_bol)
236  return;
237  for (int i = 0; i < indent; i++)
238  stream.put(' ');
239  at_bol = false;
240 }
241 
242 bool XmlWriter::IsOk() const {
243  return (stream.good());
244 }
245 
246 template void XmlWriter::WriteNode<bool>(const std::string& name, const bool& val);
247 template void XmlWriter::WriteNode<uint8_t>(const std::string& name, const uint8_t& val);
248 template void XmlWriter::WriteNode<int16_t>(const std::string& name, const int16_t& val);
249 template void XmlWriter::WriteNode<uint32_t>(const std::string& name, const uint32_t& val);
250 template void XmlWriter::WriteNode<int32_t>(const std::string& name, const int32_t& val);
251 template void XmlWriter::WriteNode<double>(const std::string& name, const double& val);
252 template void XmlWriter::WriteNode<std::string>(const std::string& name, const std::string& val);
253 template void XmlWriter::WriteNode<DBString>(const std::string& name, const DBString& val);
254 
255 template void XmlWriter::WriteNode<std::vector<bool>>(const std::string& name, const std::vector<bool>& val);
256 template void XmlWriter::WriteNode<std::vector<uint8_t>>(const std::string& name, const std::vector<uint8_t>& val);
257 template void XmlWriter::WriteNode<std::vector<int16_t>>(const std::string& name, const std::vector<int16_t>& val);
258 template void XmlWriter::WriteNode<std::vector<uint32_t>>(const std::string& name, const std::vector<uint32_t>& val);
259 template void XmlWriter::WriteNode<std::vector<int32_t>>(const std::string& name, const std::vector<int32_t>& val);
260 
261 template void XmlWriter::WriteNode<DBArray<bool>>(const std::string& name, const DBArray<bool>& val);
262 template void XmlWriter::WriteNode<DBArray<uint8_t>>(const std::string& name, const DBArray<uint8_t>& val);
263 template void XmlWriter::WriteNode<DBArray<int16_t>>(const std::string& name, const DBArray<int16_t>& val);
264 template void XmlWriter::WriteNode<DBArray<uint32_t>>(const std::string& name, const DBArray<uint32_t>& val);
265 template void XmlWriter::WriteNode<DBArray<int32_t>>(const std::string& name, const DBArray<int32_t>& val);
266 
267 } //namespace lcf
Definition: dbarray.cpp:13