liblcf
reader_flags.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 "reader_struct.h"
11 #include "rpg_trooppagecondition.h"
12 #include "rpg_eventpagecondition.h"
13 #include "rpg_terrain.h"
14 #include "rpg_savepicture.h"
15 #include "data.h"
16 
18 #include "ldb_terrain_flags.h"
20 #include "lsd_savepicture_flags.h"
21 
22 // Templates
23 
24 template <class S>
25 void 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 
51 template <class S>
52 void Flags<S>::WriteLcf(const S& obj, LcfWriter& stream) {
53  const bool db_is2k3 = (Data::system.ldb_id == 2003);
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 
77 template <class S>
78 int Flags<S>::LcfSize(const S& /* obj */, LcfWriter& /* stream */) {
79  const bool db_is2k3 = (Data::system.ldb_id == 2003);
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 
92 template <class S>
93 void Flags<S>::WriteXml(const S& obj, XmlWriter& stream) {
94  const bool db_is2k3 = (Data::system.ldb_id == 2003);
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 
107 template <class S>
108 class FlagsXmlHandler : public XmlHandler {
109 private:
110  S& obj;
111  bool* field;
112 public:
113  FlagsXmlHandler(S& obj) : obj(obj), field(NULL) {
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 
134 template <class S>
135 void 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 
146 template class Flags<RPG::Terrain::Flags>;
147 template class Flags<RPG::SavePicture::Flags>;
rpg_eventpagecondition.h
LcfReader::Read
void Read(void *ptr, size_t size, size_t nmemb)
Definition: reader_lcf.cpp:47
FlagsXmlHandler::field
bool * field
Definition: reader_flags.cpp:111
XmlReader::Error
void Error(const char *fmt,...)
Definition: reader_xml.cpp:59
XmlHandler
Definition: reader_xml.h:116
XmlReader
Definition: reader_xml.h:31
WrapperXmlHandler
Definition: reader_struct.h:705
XmlReader::SetHandler
void SetHandler(XmlHandler *handler)
Definition: reader_xml.cpp:80
rpg_savepicture.h
FlagsXmlHandler::StartElement
void StartElement(XmlReader &stream, const char *name, const char **)
Definition: reader_flags.cpp:116
XmlWriter::EndElement
void EndElement(const std::string &name)
Definition: writer_xml.cpp:177
rpg_terrain.h
FlagsXmlHandler::CharacterData
void CharacterData(XmlReader &, const std::string &data)
Definition: reader_flags.cpp:128
reader_struct.h
LcfWriter
Definition: writer_lcf.h:27
Flags::LcfSize
static int LcfSize(const S &obj, LcfWriter &stream)
Definition: reader_flags.cpp:78
FlagsXmlHandler::FlagsXmlHandler
FlagsXmlHandler(S &obj)
Definition: reader_flags.cpp:113
XmlWriter
Definition: writer_xml.h:22
FlagsXmlHandler::obj
S & obj
Definition: reader_flags.cpp:110
FlagsXmlHandler::EndElement
void EndElement(XmlReader &, const char *)
Definition: reader_flags.cpp:125
LcfWriter::Write
void Write(const void *ptr, size_t size, size_t nmemb)
Definition: writer_lcf.cpp:24
ldb_trooppagecondition_flags.h
Flags::WriteXml
static void WriteXml(const S &obj, XmlWriter &stream)
Definition: reader_flags.cpp:93
ldb_terrain_flags.h
lsd_savepicture_flags.h
rpg_trooppagecondition.h
Flags::idx
static int idx(const char *tag)
Definition: reader_struct.h:668
Data::data
RPG::Database data
Definition: data.cpp:14
data.h
Flags::ReadLcf
static void ReadLcf(S &obj, LcfReader &stream, uint32_t length)
Definition: reader_flags.cpp:25
RPG::System::ldb_id
int32_t ldb_id
Definition: rpg_system.h:177
Data::system
RPG::System & system
Definition: data.cpp:31
FlagsXmlHandler
Definition: reader_flags.cpp:108
XmlWriter::WriteNode
void WriteNode(const std::string &name, const T &val)
Definition: writer_xml.cpp:155
lmu_eventpagecondition_flags.h
Flags::BeginXml
static void BeginXml(S &obj, XmlReader &stream)
Definition: reader_flags.cpp:135
Flags
Definition: reader_struct.h:642
Flags::WriteLcf
static void WriteLcf(const S &obj, LcfWriter &stream)
Definition: reader_flags.cpp:52
LcfReader
Definition: reader_lcf.h:35
XmlWriter::BeginElement
void BeginElement(const std::string &name)
Definition: writer_xml.cpp:161