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