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