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