liblcf
reader_flags.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 "reader_struct.h"
11#include "lcf/rpg/trooppagecondition.h"
12#include "lcf/rpg/eventpagecondition.h"
13#include "lcf/rpg/terrain.h"
14#include "lcf/rpg/savepicture.h"
15
17#include "ldb_terrain_flags.h"
20
21namespace lcf {
22// Templates
23
24template <class S>
25void Flags<S>::ReadLcf(S& obj, LcfReader& stream, uint32_t length) {
26 uint8_t byte;
27 int bitidx = 0;
28 int byteidx = 0;
29 stream.Read(byte);
30 for (size_t i = 0; i < num_flags; ++i) {
31 if (bitidx == 8) {
32 ++byteidx;
33 if (byteidx >= int(length)) {
34 break;
35 }
36 stream.Read(byte);
37 bitidx = 0;
38 }
39 obj.flags[i] |= (byte >> bitidx) & 1;
40 ++bitidx;
41 }
42#ifdef LCF_DEBUG_TRACE
43 unsigned long x = 0;
44 for (size_t i = 0; i < obj.flags.size(); ++i) {
45 x |= (obj.flags[i] << i);
46 }
47 printf("0x%lx\n", x);
48#endif
49}
50
51template <class S>
52void Flags<S>::WriteLcf(const S& obj, LcfWriter& stream) {
53 const bool db_is2k3 = stream.Is2k3();
54
55 uint8_t byte = 0;
56 int bitidx = 0;
57 for (size_t i = 0; i < num_flags; ++i) {
58 const auto flag_is2k3 = flags_is2k3[i];
59 if (!db_is2k3 && flag_is2k3) {
60 continue;
61 }
62 byte |= (obj.flags[i] << bitidx);
63
64 ++bitidx;
65 if (bitidx == 8) {
66 stream.Write(byte);
67 bitidx = 0;
68 byte = 0;
69 }
70 }
71
72 if (bitidx != 0) {
73 stream.Write(byte);
74 }
75}
76
77template <class S>
78int Flags<S>::LcfSize(const S& /* obj */, LcfWriter& stream) {
79 const bool db_is2k3 = stream.Is2k3();
80 int num_bits = 0;
81 for (size_t i = 0; i < num_flags; ++i) {
82 const auto flag_is2k3 = flags_is2k3[i];
83 if (!db_is2k3 && flag_is2k3) {
84 continue;
85 }
86 ++num_bits;
87 }
88 auto num_bytes = (num_bits + 7) / 8;
89 return num_bytes;
90}
91
92template <class S>
93void Flags<S>::WriteXml(const S& obj, XmlWriter& stream) {
94 const bool db_is2k3 = stream.Is2k3();
95 stream.BeginElement(name);
96 for (size_t i = 0; i < num_flags; ++i) {
97 const auto flag_is2k3 = flags_is2k3[i];
98 if (!db_is2k3 && flag_is2k3) {
99 continue;
100 }
101 const auto* flag_name = flag_names[i];
102 stream.WriteNode<bool>(flag_name, obj.flags[i]);
103 }
104 stream.EndElement(name);
105}
106
107template <class S>
108class FlagsXmlHandler : public XmlHandler {
109private:
110 S& obj;
111 bool* field;
112public:
114 }
115
116 void StartElement(XmlReader& stream, const char* name, const char** /* atts */) {
117 const auto idx = Flags<S>::idx(name);
118 if (idx < 0) {
119 stream.Error("Unrecognized field '%s'", name);
120 field = NULL;
121 return;
122 }
123 field = &obj.flags[idx];
124 }
125 void EndElement(XmlReader& /* stream */, const char* /* name */) {
126 field = NULL;
127 }
128 void CharacterData(XmlReader& /* stream */, const std::string& data) {
129 if (field != NULL)
130 XmlReader::Read<bool>(*field, data);
131 }
132};
133
134template <class S>
135void Flags<S>::BeginXml(S& obj, XmlReader& stream) {
136 stream.SetHandler(new WrapperXmlHandler(name, new FlagsXmlHandler<S>(obj)));
137}
138
139// Instantiate templates
140#ifdef _MSC_VER
141#pragma warning (disable : 4661)
142#endif
143
146template class Flags<rpg::Terrain::Flags>;
147template class Flags<rpg::SavePicture::Flags>;
148
149} //namespace lcf
static void BeginXml(S &obj, XmlReader &stream)
static void ReadLcf(S &obj, LcfReader &stream, uint32_t length)
static void WriteXml(const S &obj, XmlWriter &stream)
static int idx(const char *tag)
static int LcfSize(const S &obj, LcfWriter &stream)
static void WriteLcf(const S &obj, LcfWriter &stream)
void CharacterData(XmlReader &, const std::string &data)
void StartElement(XmlReader &stream, const char *name, const char **)
void EndElement(XmlReader &, const char *)
Definition: dbarray.cpp:13