liblcf
writer_xml.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of liblcf. Copyright (c) 2021 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  at_bol = true;
89  Indent();
90  break;
91  case '\r':
92  case '\t':
93  stream.put(c);
94  break;
95  default:
96  if (c >= 0 && c < 32) {
97  char temp[10];
98  snprintf(temp,10, "&#x%04x;", 0xE000 + c);
99  stream << temp;
100  }
101  else
102  stream.put(c);
103  break;
104  }
105  }
106 }
107 
108 template <>
109 void XmlWriter::Write<std::string>(const std::string& val) {
110  WriteString(val);
111 }
112 
113 template <>
114 void XmlWriter::Write<DBString>(const DBString& val) {
115  WriteString(val);
116 }
117 
118 template <>
119 void XmlWriter::Write<std::vector<int32_t>>(const std::vector<int32_t>& val) {
120  WriteVector(val);
121 }
122 
123 template <>
124 void XmlWriter::Write<std::vector<bool>>(const std::vector<bool>& val) {
125  WriteVector(val);
126 }
127 
128 template <>
129 void XmlWriter::Write<std::vector<uint8_t>>(const std::vector<uint8_t>& val) {
130  WriteVector(val);
131 }
132 
133 template <>
134 void XmlWriter::Write<std::vector<int16_t>>(const std::vector<int16_t>& val) {
135  WriteVector(val);
136 }
137 
138 template <>
139 void XmlWriter::Write<std::vector<uint32_t>>(const std::vector<uint32_t>& val) {
140  WriteVector(val);
141 }
142 
143 template <>
144 void XmlWriter::Write<std::vector<double>>(const std::vector<double>& val) {
145  WriteVector(val);
146 }
147 
148 template <>
149 void XmlWriter::Write<DBArray<int32_t>>(const DBArray<int32_t>& val) {
150  WriteVector(val);
151 }
152 
153 template <>
154 void XmlWriter::Write<DBArray<bool>>(const DBArray<bool>& val) {
155  WriteVector(val);
156 }
157 
158 template <>
159 void XmlWriter::Write<DBArray<uint8_t>>(const DBArray<uint8_t>& val) {
160  WriteVector(val);
161 }
162 
163 template <>
164 void XmlWriter::Write<DBArray<int16_t>>(const DBArray<int16_t>& val) {
165  WriteVector(val);
166 }
167 
168 template <>
169 void XmlWriter::Write<DBArray<uint32_t>>(const DBArray<uint32_t>& val) {
170  WriteVector(val);
171 }
172 
173 template <>
174 void XmlWriter::Write<DBArray<double>>(const DBArray<double>& val) {
175  WriteVector(val);
176 }
177 
178 void XmlWriter::WriteInt(int val) {
179  Write<int32_t>(val);
180 }
181 
182 template <>
183 void XmlWriter::Write(const DBBitArray& val) {
184  WriteVector(val);
185 }
186 
187 template <typename ArrayType>
188 void XmlWriter::WriteVector(const ArrayType& val) {
189  Indent();
190  bool first = true;
191  for (auto&& e: val) {
192  if (!first)
193  stream.put(' ');
194  first = false;
195  Write<typename ArrayType::value_type>(e);
196  }
197 }
198 
199 template <class T>
200 void XmlWriter::WriteNode(const std::string& name, const T& val) {
201  BeginElement(name);
202  Write<T>(val);
203  EndElement(name);
204 }
205 
206 void XmlWriter::BeginElement(const std::string& name) {
207  NewLine();
208  Indent();
209  stream << "<" << name << ">";
210  indent++;
211 }
212 
213 void XmlWriter::BeginElement(const std::string& name, int ID) {
214  NewLine();
215  Indent();
216  char temp[6];
217  snprintf(temp, 6, "%04d", ID);
218  stream << "<" << name << " id=\"" << temp << "\">";
219  indent++;
220 }
221 
222 void XmlWriter::EndElement(const std::string& name) {
223  indent--;
224  Indent();
225  stream << "</" << name << ">";
226  NewLine();
227 }
228 
229 void XmlWriter::NewLine() {
230  if (at_bol)
231  return;
232  stream.put('\n');
233  at_bol = true;
234 }
235 
236 void XmlWriter::Indent() {
237  if (!at_bol)
238  return;
239  for (int i = 0; i < indent; i++)
240  stream.put(' ');
241  at_bol = false;
242 }
243 
244 bool XmlWriter::IsOk() const {
245  return (stream.good());
246 }
247 
248 template void XmlWriter::WriteNode<bool>(const std::string& name, const bool& val);
249 template void XmlWriter::WriteNode<uint8_t>(const std::string& name, const uint8_t& val);
250 template void XmlWriter::WriteNode<int16_t>(const std::string& name, const int16_t& val);
251 template void XmlWriter::WriteNode<uint32_t>(const std::string& name, const uint32_t& val);
252 template void XmlWriter::WriteNode<int32_t>(const std::string& name, const int32_t& val);
253 template void XmlWriter::WriteNode<double>(const std::string& name, const double& val);
254 template void XmlWriter::WriteNode<std::string>(const std::string& name, const std::string& val);
255 template void XmlWriter::WriteNode<DBString>(const std::string& name, const DBString& val);
256 
257 template void XmlWriter::WriteNode<std::vector<bool>>(const std::string& name, const std::vector<bool>& val);
258 template void XmlWriter::WriteNode<std::vector<uint8_t>>(const std::string& name, const std::vector<uint8_t>& val);
259 template void XmlWriter::WriteNode<std::vector<int16_t>>(const std::string& name, const std::vector<int16_t>& val);
260 template void XmlWriter::WriteNode<std::vector<uint32_t>>(const std::string& name, const std::vector<uint32_t>& val);
261 template void XmlWriter::WriteNode<std::vector<int32_t>>(const std::string& name, const std::vector<int32_t>& val);
262 
263 template void XmlWriter::WriteNode<DBArray<bool>>(const std::string& name, const DBArray<bool>& val);
264 template void XmlWriter::WriteNode<DBArray<uint8_t>>(const std::string& name, const DBArray<uint8_t>& val);
265 template void XmlWriter::WriteNode<DBArray<int16_t>>(const std::string& name, const DBArray<int16_t>& val);
266 template void XmlWriter::WriteNode<DBArray<uint32_t>>(const std::string& name, const DBArray<uint32_t>& val);
267 template void XmlWriter::WriteNode<DBArray<int32_t>>(const std::string& name, const DBArray<int32_t>& val);
268 
269 } //namespace lcf
Definition: dbarray.cpp:13