liblcf
writer_lcf.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 
12 #include "lcf/writer_lcf.h"
13 
14 namespace lcf {
15 
16 LcfWriter::LcfWriter(std::ostream& filestream, EngineVersion engine, std::string encoding)
17  : stream(filestream)
18  , encoder(std::move(encoding))
19  , engine(engine)
20 {
21 }
22 
23 void LcfWriter::Write(const void *ptr, size_t size, size_t nmemb) {
24  stream.write(reinterpret_cast<const char*>(ptr), size*nmemb);
25  assert(stream.good());
26 }
27 
28 template <>
29 void LcfWriter::Write<int8_t>(int8_t val) {
30  Write(&val, 1, 1);
31 }
32 
33 template <>
34 void LcfWriter::Write<uint8_t>(uint8_t val) {
35  Write(&val, 1, 1);
36 }
37 
38 template <>
39 void LcfWriter::Write<int16_t>(int16_t val) {
40  SwapByteOrder(val);
41  Write(&val, 2, 1);
42 }
43 
44 template <>
45 void LcfWriter::Write<uint32_t>(uint32_t val) {
46  SwapByteOrder(val);
47  Write(&val, 4, 1);
48 }
49 
50 void LcfWriter::WriteInt(int val) {
51  uint32_t value = (uint32_t) val;
52  for (int i = 28; i >= 0; i -= 7)
53  if (value >= (1U << i) || i == 0)
54  Write<uint8_t>((uint8_t)(((value >> i) & 0x7F) | (i > 0 ? 0x80 : 0)));
55 }
56 
57 void LcfWriter::WriteUInt64(uint64_t value) {
58  for (int i = 56; i >= 0; i -= 7)
59  if (value >= (1LL << i) || i == 0)
60  Write<uint8_t>((uint8_t)(((value >> i) & 0x7F) | (i > 0 ? 0x80 : 0)));
61 }
62 
63 template <>
64 void LcfWriter::Write<int32_t>(int32_t val) {
65  WriteInt(val);
66 }
67 
68 template <>
69 void LcfWriter::Write<bool>(bool val) {
70  uint8_t x = val ? 1 : 0;
71  Write(x);
72 }
73 
74 template <>
75 void LcfWriter::Write<double>(double val) {
76  SwapByteOrder(val);
77  Write(&val, 8, 1);
78 }
79 
80 template <>
81 void LcfWriter::Write<bool>(const std::vector<bool>& buffer) {
82  std::vector<bool>::const_iterator it;
83  for (it = buffer.begin(); it != buffer.end(); it++) {
84  uint8_t val = *it ? 1 : 0;
85  Write(val);
86  }
87 }
88 
89 template <>
90 void LcfWriter::Write<uint8_t>(const std::vector<uint8_t>& buffer) {
91  Write(&buffer.front(), 1, buffer.size());
92 }
93 
94 template <>
95 void LcfWriter::Write<int16_t>(const std::vector<int16_t>& buffer) {
96  std::vector<int16_t>::const_iterator it;
97  for (it = buffer.begin(); it != buffer.end(); it++)
98  Write(*it);
99 }
100 
101 template <>
102 void LcfWriter::Write<int32_t>(const std::vector<int32_t>& buffer) {
103  std::vector<int32_t>::const_iterator it;
104  for (it = buffer.begin(); it != buffer.end(); it++) {
105  int32_t val = *it;
106  SwapByteOrder(val);
107  // Write<int32_t> writes a compressed integer
108  Write(&val, 4, 1);
109  }
110 }
111 
112 template <>
113 void LcfWriter::Write<uint32_t>(const std::vector<uint32_t>& buffer) {
114  std::vector<uint32_t>::const_iterator it;
115  for (it = buffer.begin(); it != buffer.end(); it++)
116  Write(*it);
117 }
118 
119 void LcfWriter::Write(const std::string& _str) {
120  std::string str = Decode(_str);
121  if (!str.empty()) {
122  Write(&*str.begin(), 1, str.size());
123  }
124 }
125 
126 void LcfWriter::Write(const DBString& _str) {
127  std::string str = Decode(_str);
128  if (!str.empty()) {
129  Write(&*str.begin(), 1, str.size());
130  }
131 }
132 
133 void LcfWriter::Write(const DBBitArray& bits) {
134  for (auto& b: bits) {
135  Write(static_cast<uint8_t>(b));
136  }
137 }
138 
139 uint32_t LcfWriter::Tell() {
140  return (uint32_t)stream.tellp();
141 }
142 
143 bool LcfWriter::IsOk() const {
144  return stream.good() && encoder.IsOk();
145 }
146 
147 std::string LcfWriter::Decode(StringView str) {
148  auto copy = std::string(str);
149  encoder.Decode(copy);
150  return copy;
151 }
152 
153 #ifdef WORDS_BIGENDIAN
154 void LcfWriter::SwapByteOrder(uint16_t& us)
155 {
156  us = (us >> 8) |
157  (us << 8);
158 }
159 
160 void LcfWriter::SwapByteOrder(uint32_t& ui)
161 {
162  ui = (ui >> 24) |
163  ((ui<<8) & 0x00FF0000) |
164  ((ui>>8) & 0x0000FF00) |
165  (ui << 24);
166 }
167 
168 void LcfWriter::SwapByteOrder(double& d)
169 {
170  char *p = reinterpret_cast<char*>(&d);
171  std::swap(p[0], p[7]);
172  std::swap(p[1], p[6]);
173  std::swap(p[2], p[5]);
174  std::swap(p[3], p[4]);
175 }
176 #else
177 void LcfWriter::SwapByteOrder(uint16_t& /* us */) {}
178 void LcfWriter::SwapByteOrder(uint32_t& /* ui */) {}
179 void LcfWriter::SwapByteOrder(double& /* d */) {}
180 #endif
181 
182 void LcfWriter::SwapByteOrder(int16_t& s)
183 {
184  SwapByteOrder((uint16_t&) s);
185 }
186 
187 void LcfWriter::SwapByteOrder(int32_t& s)
188 {
189  SwapByteOrder((uint32_t&) s);
190 }
191 
192 } //namespace lcf
Definition: dbarray.cpp:13