liblcf
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
reader_flags.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 liblcf authors
3  * This file is released under the MIT License
4  * http://opensource.org/licenses/MIT
5  */
6 
7 #include "reader_struct.h"
10 #include "rpg_terrain.h"
11 
12 // Templates
13 
14 template <class S>
16  if (!tag_map.empty())
17  return;
18  for (int i = 0; flags[i] != NULL; i++)
19  tag_map[flags[i]->name] = flags[i];
20 }
21 
22 template <class S>
23 void Flags<S>::ReadLcf(S& obj, LcfReader& stream, uint32_t length) {
24  assert(length >= 1 && length <= max_size);
25  uint8_t bitflag;
26  for (int i = 0; flags[i] != NULL; i++) {
27  if (i % 8 == 0) {
28  if (i / 8 >= (int) length)
29  break;
30  stream.Read(bitflag);
31  }
32  bool S::*ref = flags[i]->ref;
33  obj.*ref = ((bitflag >> (i % 8)) & 0x1) != 0;
34  }
35 }
36 
37 template <class S>
38 void Flags<S>::WriteLcf(const S& obj, LcfWriter& stream) {
39  uint8_t bitflag = 0;
40  for (int i = 0; flags[i] != NULL; i++) {
41  if (i % 8 == 0) {
42  if (i > 0)
43  stream.Write(bitflag);
44  bitflag = 0;
45  }
46  bool S::*ref = flags[i]->ref;
47  if (obj.*ref)
48  bitflag |= (1 << (i % 8));
49  }
50 
51  if (bitflag != 0 || max_size == 1)
52  stream.Write(bitflag);
53 }
54 
55 template <class S>
56 int Flags<S>::LcfSize(const S& obj, LcfWriter& /* stream */) {
57  int result = 0;
58  for (int i = 0; flags[i] != NULL; i++) {
59  bool S::*ref = flags[i]->ref;
60  if (obj.*ref)
61  result = i / 8;
62  }
63  return result + 1;
64 }
65 
66 template <class S>
67 void Flags<S>::WriteXml(const S& obj, XmlWriter& stream) {
68  stream.BeginElement(name);
69  for (int i = 0; flags[i] != NULL; i++) {
70  const Flag* flag = flags[i];
71  bool S::*ref = flag->ref;
72  stream.WriteNode<bool>(flag->name, obj.*ref);
73  }
74  stream.EndElement(name);
75 }
76 
77 template <class S>
78 class FlagsXmlHandler : public XmlHandler {
79 private:
80  S& obj;
81  bool* field;
82 public:
83  FlagsXmlHandler(S& obj) : obj(obj), field(NULL) {
85  }
86 
87  void StartElement(XmlReader& stream, const char* name, const char** /* atts */) {
88  const typename Flags<S>::Flag* flag = Flags<S>::tag_map[name];
89  if (flag != NULL) {
90  bool S::*ref = flag->ref;
91  field = &(obj.*ref);
92  }
93  else {
94  stream.Error("Unrecognized field '%s'", name);
95  field = NULL;
96  }
97  }
98  void EndElement(XmlReader& /* stream */, const char* /* name */) {
99  field = NULL;
100  }
101  void CharacterData(XmlReader& /* stream */, const std::string& data) {
102  if (field != NULL)
103  XmlReader::Read<bool>(*field, data);
104  }
105 };
106 
107 template <class S>
108 void Flags<S>::BeginXml(S& obj, XmlReader& stream) {
109  stream.SetHandler(new WrapperXmlHandler(name, new FlagsXmlHandler<S>(obj)));
110 }
111 
112 // Instantiate templates
113 
116 template class Flags<RPG::Terrain::Flags>;
RPG::Database data
Definition: data.cpp:11
bool S::* ref
static void WriteXml(const S &obj, XmlWriter &stream)
void SetHandler(XmlHandler *handler)
Definition: reader_xml.cpp:92
void BeginElement(const std::string &name)
Definition: writer_xml.cpp:163
void Read(void *ptr, size_t size, size_t nmemb)
Definition: reader_lcf.cpp:52
void EndElement(const std::string &name)
Definition: writer_xml.cpp:177
void Error(const char *fmt,...)
Definition: reader_xml.cpp:71
void EndElement(XmlReader &, const char *)
static void ReadLcf(S &obj, LcfReader &stream, uint32_t length)
static void BeginXml(S &obj, XmlReader &stream)
void Write(const void *ptr, size_t size, size_t nmemb)
Definition: writer_lcf.cpp:33
void StartElement(XmlReader &stream, const char *name, const char **)
static void WriteLcf(const S &obj, LcfWriter &stream)
FlagsXmlHandler(S &obj)
const char *const name
static void MakeTagMap()
void CharacterData(XmlReader &, const std::string &data)
static int LcfSize(const S &obj, LcfWriter &stream)
void WriteNode(const std::string &name, const T &val)
Definition: writer_xml.cpp:157