liblcf
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"
19 #include "lsd_savepicture_flags.h"
22 
23 namespace lcf {
24 // Templates
25 
26 template <class S>
27 void Flags<S>::ReadLcf(S& obj, LcfReader& stream, uint32_t length) {
28  uint8_t byte;
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 
53 template <class S>
54 void Flags<S>::WriteLcf(const S& obj, LcfWriter& stream) {
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 
79 template <class S>
80 int 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 
94 template <class S>
95 void Flags<S>::WriteXml(const S& obj, XmlWriter& stream) {
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 
109 template <class S>
110 class FlagsXmlHandler : public XmlHandler {
111 private:
112  S& obj;
113  bool* field;
114 public:
115  FlagsXmlHandler(S& obj) : obj(obj), field(NULL) {
116  }
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 
136 template <class S>
137 void Flags<S>::BeginXml(S& obj, XmlReader& stream) {
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
149 template class Flags<rpg::Terrain::Flags>;
150 template 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 *)
Definition: dbarray.cpp:13