liblcf
reader_struct.h
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 #ifndef LCF_READER_STRUCT_H
11 #define LCF_READER_STRUCT_H
12 
13 #ifdef LCF_DEBUG_TRACE
14 #include <iostream>
15 #endif
16 #include <string>
17 #include <vector>
18 #include <map>
19 #include <memory>
20 #include <cstring>
21 #include <cstdlib>
22 #include <cinttypes>
23 #include "reader_lcf.h"
24 #include "writer_lcf.h"
25 #include "reader_xml.h"
26 #include "writer_xml.h"
27 #include "rpg_eventpagecondition.h"
28 #include "rpg_trooppagecondition.h"
29 #include "rpg_terrain.h"
30 #include "rpg_equipment.h"
31 #include "rpg_parameters.h"
32 #include "rpg_eventcommand.h"
33 #include "rpg_movecommand.h"
34 #include "rpg_treemap.h"
35 #include "rpg_rect.h"
36 #include "rpg_savepicture.h"
37 #include "rpg_terms.h"
38 #include "data.h"
39 
40 // Forward declarations
41 
42 template <class T>
43 class Struct;
44 
45 // Type categories
46 
47 struct Category {
48  enum Index {
52  RawStruct
53  };
54 };
55 
56 template <class T>
57 struct TypeCategory {
59 };
60 
61 template <> struct TypeCategory<RPG::TroopPageCondition::Flags> { static const Category::Index value = Category::Flags; };
62 template <> struct TypeCategory<RPG::EventPageCondition::Flags> { static const Category::Index value = Category::Flags; };
63 template <> struct TypeCategory<RPG::Terrain::Flags> { static const Category::Index value = Category::Flags; };
64 template <> struct TypeCategory<RPG::SavePicture::Flags> { static const Category::Index value = Category::Flags; };
65 
66 template <> struct TypeCategory<RPG::Equipment> { static const Category::Index value = Category::RawStruct; };
67 template <> struct TypeCategory<RPG::EventCommand> { static const Category::Index value = Category::RawStruct; };
68 template <> struct TypeCategory<RPG::MoveCommand> { static const Category::Index value = Category::RawStruct; };
69 template <> struct TypeCategory<RPG::Parameters> { static const Category::Index value = Category::RawStruct; };
70 template <> struct TypeCategory<RPG::TreeMap> { static const Category::Index value = Category::RawStruct; };
71 template <> struct TypeCategory<RPG::Rect> { static const Category::Index value = Category::RawStruct; };
72 
73 template <> struct TypeCategory<int8_t> { static const Category::Index value = Category::Primitive; };
74 template <> struct TypeCategory<uint8_t> { static const Category::Index value = Category::Primitive; };
75 template <> struct TypeCategory<int16_t> { static const Category::Index value = Category::Primitive; };
76 template <> struct TypeCategory<uint32_t> { static const Category::Index value = Category::Primitive; };
77 template <> struct TypeCategory<int32_t> { static const Category::Index value = Category::Primitive; };
78 template <> struct TypeCategory<bool> { static const Category::Index value = Category::Primitive; };
79 template <> struct TypeCategory<double> { static const Category::Index value = Category::Primitive; };
80 template <> struct TypeCategory<std::string> { static const Category::Index value = Category::Primitive; };
81 
82 template <class T>
83 struct TypeCategory<std::vector<T>> {
85 };
86 
90 template <class T, Category::Index cat = TypeCategory<T>::value>
91 struct TypeReader {};
92 
96 template <class T>
97 struct RawStruct {
98  static void ReadLcf(T& ref, LcfReader& stream, uint32_t length);
99  static void WriteLcf(const T& ref, LcfWriter& stream);
100  static int LcfSize(const T& ref, LcfWriter& stream);
101  static void WriteXml(const T& ref, XmlWriter& stream);
102  static void BeginXml(T& ref, XmlReader& stream);
103 };
104 
105 template <class T>
107  static void ReadLcf(T& ref, LcfReader& stream, uint32_t length) {
108  RawStruct<T>::ReadLcf(ref, stream, length);
109  }
110  static void WriteLcf(const T& ref, LcfWriter& stream) {
111  RawStruct<T>::WriteLcf(ref, stream);
112  }
113  static int LcfSize(const T& ref, LcfWriter& stream) {
114  return RawStruct<T>::LcfSize(ref, stream);
115  }
116  static void WriteXml(const T& ref, XmlWriter& stream) {
117  RawStruct<T>::WriteXml(ref, stream);
118  }
119  static void BeginXml(T& ref, XmlReader& stream) {
120  RawStruct<T>::BeginXml(ref, stream);
121  }
122  static void ParseXml(T& /* ref */, const std::string& /* data */) {
123  //no-op
124  }
125 };
126 
130 template <class T>
131 struct LcfSizeT {
132  static const uint32_t value = sizeof(T);
133 };
134 
138 template <>
139 struct LcfSizeT<bool> {
140  static const uint32_t value = 1;
141 };
142 
146 template <class T>
147 struct Primitive {
148  static void ReadLcf(T& ref, LcfReader& stream, uint32_t length) {
149  int dif = 0;
150  // FIXME: Bug #174
151  if (length != LcfSizeT<T>::value) {
152  dif = length - LcfSizeT<T>::value;
153  fprintf(stderr, "Reading Primitive of incorrect size %" PRIu32 " (expected %" PRIu32 ") at %" PRIX32 "\n",
154  length, LcfSizeT<T>::value, stream.Tell());
155  }
156 
157  stream.Read(ref);
158 #ifdef LCF_DEBUG_TRACE
159  DebugPrint(ref);
160 #endif
161 
162  if (dif != 0) {
163  // Fix incorrect read pointer position
164 #ifdef LCF_DEBUG_TRACE
165  printf("Invalid %s at %X\n", typeid(T).name(), stream.Tell());
166 #endif
167  stream.Seek(dif, LcfReader::FromCurrent);
168  }
169  }
170  static void WriteLcf(const T& ref, LcfWriter& stream) {
171  stream.Write(ref);
172  }
173  static int LcfSize(const T& /* ref */, LcfWriter& /* stream */) {
174  return LcfSizeT<T>::value;
175  }
176  static void WriteXml(const T& ref, XmlWriter& stream) {
177  stream.Write(ref);
178  }
179  static void ParseXml(T& ref, const std::string& data) {
180  XmlReader::Read(ref, data);
181  }
182  private:
183 #ifdef LCF_DEBUG_TRACE
184  template <typename U>
185  static void DebugPrint(U& ref) {
186  std::cout << ref << '\n';
187  }
188  static void DebugPrint(int8_t ref) {
189  std::cout << (int)ref << '\n';
190  }
191  static void DebugPrint(uint8_t ref) {
192  std::cout << (int)ref << '\n';
193  }
194 #endif
195 };
196 
200 template <class T>
201 struct Primitive<std::vector<T>> {
202  static void ReadLcf(std::vector<T>& ref, LcfReader& stream, uint32_t length) {
203  stream.Read(ref, length);
204 #ifdef LCF_DEBUG_TRACE
205  typename std::vector<T>::iterator it;
206  printf(" ");
207  for (it = ref.begin(); it != ref.end(); ++it) {
208  printf("%d, ", static_cast<int>(*it));
209  }
210  printf("\n");
211 #endif
212  }
213  static void WriteLcf(const std::vector<T>& ref, LcfWriter& stream) {
214  stream.Write(ref);
215  }
216  static int LcfSize(const std::vector<T>& ref, LcfWriter& /* stream */) {
217  return LcfSizeT<T>::value * ref.size();
218  }
219  static void WriteXml(const std::vector<T>& ref, XmlWriter& stream) {
220  stream.Write(ref);
221  }
222  static void ParseXml(std::vector<T>& ref, const std::string& data) {
223  XmlReader::Read(ref, data);
224  }
225 };
226 
230 template <>
231 struct Primitive<int32_t> {
232  static void ReadLcf(int32_t& ref, LcfReader& stream, uint32_t length) {
233  if (length >= 1 && length <= 5) {
234  ref = stream.ReadInt();
235 #ifdef LCF_DEBUG_TRACE
236  printf(" %d\n", ref);
237 #endif
238  } else {
239  ref = 0;
240 #ifdef LCF_DEBUG_TRACE
241  printf("Invalid integer at %X\n", stream.Tell());
242 #endif
243  stream.Seek(length, LcfReader::FromCurrent);
244  }
245 
246  }
247  static void WriteLcf(const int32_t& ref, LcfWriter& stream) {
248  stream.WriteInt(ref);
249  }
250  static int LcfSize(const int32_t& ref, LcfWriter& /* stream */) {
251  return LcfReader::IntSize(ref);
252  }
253  static void WriteXml(const int32_t& ref, XmlWriter& stream) {
254  stream.WriteInt(ref);
255  }
256  static void ParseXml(int32_t& ref, const std::string& data) {
257  XmlReader::Read(ref, data);
258  }
259 };
260 
264 template <>
265 struct Primitive<std::string> {
266  static void ReadLcf(std::string& ref, LcfReader& stream, uint32_t length) {
267  stream.ReadString(ref, length);
268 #ifdef LCF_DEBUG_TRACE
269  printf(" %s\n", ref.c_str());
270 #endif
271  }
272  static void WriteLcf(const std::string& ref, LcfWriter& stream) {
273  stream.Write(ref);
274  }
275  static int LcfSize(const std::string& ref, LcfWriter& stream) {
276  return stream.Decode(ref).size();
277  }
278  static void WriteXml(const std::string& ref, XmlWriter& stream) {
279  stream.Write(ref);
280  }
281  static void ParseXml(std::string& ref, const std::string& data) {
282  XmlReader::Read(ref, data);
283  }
284 };
285 
289 template <class T>
291  static void ReadLcf(T& ref, LcfReader& stream, uint32_t length) {
292  Primitive<T>::ReadLcf(ref, stream, length);
293  }
294  static void WriteLcf(const T& ref, LcfWriter& stream) {
295  Primitive<T>::WriteLcf(ref, stream);
296  }
297  static int LcfSize(const T& ref, LcfWriter& stream) {
298  return Primitive<T>::LcfSize(ref, stream);
299  }
300  static void WriteXml(const T& ref, XmlWriter& stream) {
301  Primitive<T>::WriteXml(ref, stream);
302  }
303  static void BeginXml(T& /* ref */, XmlReader& /* stream */) {
304  // no-op
305  }
306  static void ParseXml(T& ref, const std::string& data) {
308  }
309 };
310 
314 template <class S>
315 struct Field {
316  typedef S struct_type;
317 
318  const char* const name;
319  int id;
321  bool is2k3;
322 
323  virtual void ReadLcf(S& obj, LcfReader& stream, uint32_t length) const = 0;
324  virtual void WriteLcf(const S& obj, LcfWriter& stream) const = 0;
325  virtual int LcfSize(const S& obj, LcfWriter& stream) const = 0;
326  virtual bool IsDefault(const S& obj, const S& ref) const = 0;
327  virtual void WriteXml(const S& obj, XmlWriter& stream) const = 0;
328  virtual void BeginXml(S& obj, XmlReader& stream) const = 0;
329  virtual void ParseXml(S& obj, const std::string& data) const = 0;
330 
331  bool isPresentIfDefault(bool db_is2k3) const {
332  if (std::is_same<S,RPG::Terms>::value && db_is2k3 && (id == 0x3 || id == 0x1)) {
333  //Special case - only known fields that are 2k specific and not
334  //written to a 2k3 db if defaulted.
335  return false;
336  }
337  return present_if_default;
338  }
339 
340  Field(int id, const char* name, bool present_if_default, bool is2k3) :
342 };
343 
347 template <class S, class T>
348 struct TypedField : public Field<S> {
349  T S::*ref;
350 
351  void ReadLcf(S& obj, LcfReader& stream, uint32_t length) const {
352  TypeReader<T>::ReadLcf(obj.*ref, stream, length);
353  }
354  void WriteLcf(const S& obj, LcfWriter& stream) const {
355  TypeReader<T>::WriteLcf(obj.*ref, stream);
356  }
357  int LcfSize(const S& obj, LcfWriter& stream) const {
358  return TypeReader<T>::LcfSize(obj.*ref, stream);
359  }
360  void WriteXml(const S& obj, XmlWriter& stream) const {
361  stream.BeginElement(this->name);
362  TypeReader<T>::WriteXml(obj.*ref, stream);
363  stream.EndElement(this->name);
364  }
365  void BeginXml(S& obj, XmlReader& stream) const {
366  TypeReader<T>::BeginXml(obj.*ref, stream);
367  }
368  void ParseXml(S& obj, const std::string& data) const {
370  }
371  bool IsDefault(const S& a, const S& b) const {
372  return a.*ref == b.*ref;
373  }
374 
375  TypedField(T S::*ref, int id, const char* name, bool present_if_default, bool is2k3) :
377 };
378 
383 template <typename S, typename T>
384 struct DatabaseVersionField : public TypedField<S,T> {
385 
387 
388  int LcfSize(const S& obj, LcfWriter& stream) const {
389  //If db version is 0, it's like a "version block" is not present.
390  if ((obj.*(this->ref)) == 0) {
391  return 0;
392  }
393  return TypedField<S,T>::LcfSize(obj, stream);
394  }
395  bool IsDefault(const S& a, const S& b) const {
396  if (Data::system.ldb_id == 2003) {
397  //DB Version always present in 2k3 db
398  return false;
399  }
400  //Only present if not 0 in 2k db.
401  return TypedField<S,T>::IsDefault(a, b);
402  }
403 };
404 
409 template <typename S>
410 struct EmptyField : public Field<S> {
411 
412  using Field<S>::Field;
413 
414  void ReadLcf(S& /* obj */, LcfReader& /* stream */, uint32_t /* length */) const { }
415  void WriteLcf(const S& /* obj */, LcfWriter& /* stream */) const { }
416  int LcfSize(const S& /* obj */, LcfWriter& /* stream */) const {
417  //This is always an "empty block"
418  return 0;
419  }
420  void WriteXml(const S& /* obj */, XmlWriter& /* stream */) const { }
421  void BeginXml(S& /* obj */, XmlReader& /* stream */) const { }
422  void ParseXml(S& /* obj */, const std::string& /* data */) const { }
423 
424  bool IsDefault(const S& /* a */, const S& /* b */) const {
425  return true;
426  }
427 
428 };
429 
430 
431 
435 template <class S, class T>
436 struct SizeField : public Field<S> {
437  const std::vector<T> S::*ref;
438 
439  void ReadLcf(S& /* obj */, LcfReader& stream, uint32_t length) const {
440  int32_t dummy;
441  TypeReader<int32_t>::ReadLcf(dummy, stream, length);
442  }
443  void WriteLcf(const S& obj, LcfWriter& stream) const {
444  int size = TypeReader<std::vector<T>>::LcfSize(obj.*ref, stream);
445  TypeReader<int32_t>::WriteLcf(size, stream);
446  }
447  int LcfSize(const S& obj, LcfWriter& stream) const {
448  int size = TypeReader<std::vector<T>>::LcfSize(obj.*ref, stream);
449  return LcfReader::IntSize(size);
450  }
451  void WriteXml(const S& /* obj */, XmlWriter& /* stream */) const {
452  // no-op
453  }
454  void BeginXml(S& /* obj */, XmlReader& /* stream */) const {
455  // no-op
456  }
457  void ParseXml(S& /* obj */, const std::string& /* data */) const {
458  // no-op
459  }
460  bool IsDefault(const S& a, const S& b) const {
461  return (a.*ref).size() == (b.*ref).size();
462  }
463 
464  SizeField(const std::vector<T> S::*ref, int id, bool present_if_default, bool is2k3) :
465  Field<S>(id, "", present_if_default, is2k3), ref(ref) {}
466 };
467 
468 
472 template <class S, class T>
473 struct CountField : public SizeField<S,T> {
474 
476 
477  void WriteLcf(const S& obj, LcfWriter& stream) const {
478  int size = (obj.*(this->ref)).size();
479  TypeReader<int32_t>::WriteLcf(size, stream);
480  }
481  int LcfSize(const S& obj, LcfWriter& /* stream */) const {
482  int size = (obj.*(this->ref)).size();
483  return LcfReader::IntSize(size);
484  }
485 };
486 
490 template <class T>
491 struct IDChecker {
492  typedef char no;
493  typedef int yes;
494 
495  template <typename U, U> struct type_check;
496  template <class C>
498  template <class C>
499  static no check(...);
500 
501  static const bool value = sizeof(check<T>(0)) == sizeof(yes);
502 };
503 
504 // ID reader for Struct class
505 
506 template <class S, bool T>
507 struct IDReaderT {
508 };
509 
510 template <class S>
511 struct IDReaderT<S, true> {
512  static void ReadID(S& obj, LcfReader& stream) {
513  obj.ID = stream.ReadInt();
514  }
515  static void WriteID(const S& obj, LcfWriter& stream) {
516  stream.WriteInt(obj.ID);
517  }
518  static int IDSize(const S& obj) {
519  return LcfReader::IntSize(obj.ID);
520  }
521  static void WriteXmlTag(const S& obj, const std::string& name, XmlWriter& stream) {
522  stream.BeginElement(name, obj.ID);
523  }
524  static void ReadIDXml(S& obj, const char** atts) {
525  for (int i = 0; atts[i] != NULL && atts[i + 1] != NULL; i += 2) {
526  if (strcmp(atts[i], "id") == 0)
527  obj.ID = atoi(atts[i + 1]);
528  }
529  }
530 };
531 
532 template <class S>
533 struct IDReaderT<S, false> {
534  static void ReadID(S& /* obj */, LcfReader& /* stream */) {}
535  static void WriteID(const S& /* obj */, LcfWriter& /* stream */) {}
536  static int IDSize(const S& /* obj */) { return 0; }
537  static void WriteXmlTag(const S& /* obj */, const std::string& name, XmlWriter& stream) {
538  stream.BeginElement(name);
539  }
540  static void ReadIDXml(S& /* obj */, const char** /* atts */) {}
541 };
542 
544  bool operator() (const char* const& lhs, const char* const& rhs) const {
545  return strcmp(lhs, rhs) < 0;
546  }
547 };
548 
549 // Struct class template
550 
551 template <class S>
552 class Struct {
553 private:
554  typedef std::map<int, const Field<S>* > field_map_type;
555  typedef std::map<const char* const, const Field<S>*, StringComparator> tag_map_type;
557  static const Field<S>* fields[];
560  static const char* const name;
561 
562  static void MakeFieldMap();
563  static void MakeTagMap();
564 
565  template <class T> friend class StructXmlHandler;
566  template <class T> friend class StructVectorXmlHandler;
567  template <class T> friend class StructFieldXmlHandler;
568 
569 public:
570  static void ReadLcf(S& obj, LcfReader& stream);
571  static void WriteLcf(const S& obj, LcfWriter& stream);
572  static int LcfSize(const S& obj, LcfWriter& stream);
573  static void WriteXml(const S& obj, XmlWriter& stream);
574  static void BeginXml(S& obj, XmlReader& stream);
575 
576  static void ReadLcf(std::vector<S>& obj, LcfReader& stream);
577  static void WriteLcf(const std::vector<S>& obj, LcfWriter& stream);
578  static int LcfSize(const std::vector<S>& obj, LcfWriter& stream);
579  static void WriteXml(const std::vector<S>& obj, XmlWriter& stream);
580  static void BeginXml(std::vector<S>& obj, XmlReader& stream);
581 };
582 
583 template <class S>
584 std::map<int, const Field<S>* > Struct<S>::field_map;
585 
586 template <class S>
587 std::map<const char* const, const Field<S>*, StringComparator> Struct<S>::tag_map;
588 
592 template <class T>
594  static void ReadLcf(T& ref, LcfReader& stream, uint32_t /* length */) {
595  Struct<T>::ReadLcf(ref, stream);
596  }
597  static void WriteLcf(const T& ref, LcfWriter& stream) {
598  Struct<T>::WriteLcf(ref, stream);
599  }
600  static int LcfSize(const T& ref, LcfWriter& stream) {
601  return Struct<T>::LcfSize(ref, stream);
602  }
603  static void WriteXml(const T& ref, XmlWriter& stream) {
604  Struct<T>::WriteXml(ref, stream);
605  }
606  static void BeginXml(T& ref, XmlReader& stream) {
607  Struct<T>::BeginXml(ref, stream);
608  }
609  static void ParseXml(T& /* ref */, const std::string& /* data */) {
610  // no-op
611  }
612 };
613 
614 template <class T>
615 struct TypeReader<std::vector<T>, Category::Struct> {
616  static void ReadLcf(std::vector<T>& ref, LcfReader& stream, uint32_t /* length */) {
617  Struct<T>::ReadLcf(ref, stream);
618  }
619  static void WriteLcf(const std::vector<T>& ref, LcfWriter& stream) {
620  Struct<T>::WriteLcf(ref, stream);
621  }
622  static int LcfSize(const std::vector<T>& ref, LcfWriter& stream) {
623  return Struct<T>::LcfSize(ref, stream);
624  }
625  static void WriteXml(const std::vector<T>& ref, XmlWriter& stream) {
626  Struct<T>::WriteXml(ref, stream);
627  }
628  static void BeginXml(std::vector<T>& ref, XmlReader& stream) {
629  Struct<T>::BeginXml(ref, stream);
630  }
631  static void ParseXml(std::vector<T>& /* ref */, const std::string& /* data */) {
632  // no-op
633  }
634 };
635 
636 
637 
641 template <class S>
642 class Flags {
643 private:
644  static const char* const name;
645  static constexpr size_t num_flags = std::tuple_size<decltype(S::flags)>::value;
646  static const std::array<const char* const, num_flags> flag_names;
647  static const std::array<bool, num_flags> flags_is2k3;
648 
649  static const char* tag(int idx);
650  static int idx(const char* tag);
651 
652  template <class T> friend class FlagsXmlHandler;
653 
654 public:
655  static void ReadLcf(S& obj, LcfReader& stream, uint32_t length);
656  static void WriteLcf(const S& obj, LcfWriter& stream);
657  static int LcfSize(const S& obj, LcfWriter& stream);
658  static void WriteXml(const S& obj, XmlWriter& stream);
659  static void BeginXml(S& obj, XmlReader& stream);
660 };
661 
662 template <class S>
663 inline const char* Flags<S>::tag(int idx) {
664  return Flags<S>::flag_names[idx];
665 }
666 
667 template <class S>
668 inline int Flags<S>::idx(const char* tag) {
669  for (size_t i = 0; i < flag_names.size(); ++i) {
670  if (std::strcmp(flag_names[i], tag) == 0) {
671  return i;
672  }
673  }
674  return -1;
675 }
676 
680 template <class T>
681 struct TypeReader<T, Category::Flags> {
682  static void ReadLcf(T& ref, LcfReader& stream, uint32_t length) {
683  Flags<T>::ReadLcf(ref, stream, length);
684  }
685  static void WriteLcf(const T& ref, LcfWriter& stream) {
686  Flags<T>::WriteLcf(ref, stream);
687  }
688  static int LcfSize(const T& ref, LcfWriter& stream) {
689  return Flags<T>::LcfSize(ref, stream);
690  }
691  static void WriteXml(const T& ref, XmlWriter& stream) {
692  Flags<T>::WriteXml(ref, stream);
693  }
694  static void BeginXml(T& ref, XmlReader& stream) {
695  Flags<T>::BeginXml(ref, stream);
696  }
697  static void ParseXml(T& /* ref */, const std::string& /* data */) {
698  // no-op
699  }
700 };
701 
706 public:
707  WrapperXmlHandler(const char* const name, XmlHandler* handler) :
708  name(name), handler(handler) {}
709 
710  void StartElement(XmlReader& stream, const char* name, const char** /* atts */) {
711  if (strcmp(name, this->name) != 0)
712  stream.Error("Expecting %s but got %s", this->name, name);
713  stream.SetHandler(handler);
714  }
715 
716 private:
717  const char* const name;
719 };
720 
724 template <class S>
725 class RootXmlHandler : public XmlHandler {
726 
727 public:
728  RootXmlHandler(S& ref, const char* const name) : ref(ref), name(name) {}
729 
730  void StartElement(XmlReader& stream, const char* name, const char** /* atts */) {
731  if (strcmp(name, this->name) != 0)
732  stream.Error("Expecting %s but got %s", this->name, name);
733  TypeReader<S>::BeginXml(ref, stream);
734  }
735 
736 private:
737  S& ref;
738  const char* const name;
739 
740 };
741 
742 #endif
static const std::array< bool, num_flags > flags_is2k3
static const char *const name
static void WriteLcf(const S &obj, LcfWriter &stream)
static void ReadLcf(S &obj, LcfReader &stream, uint32_t length)
static void BeginXml(S &obj, XmlReader &stream)
static const char * tag(int idx)
static void WriteXml(const S &obj, XmlWriter &stream)
static int idx(const char *tag)
static const std::array< const char *const, num_flags > flag_names
static constexpr size_t num_flags
static int LcfSize(const S &obj, LcfWriter &stream)
static int IntSize(unsigned int x)
Definition: reader_lcf.cpp:299
void Seek(size_t pos, SeekMode mode=FromStart)
Definition: reader_lcf.cpp:200
int ReadInt()
Definition: reader_lcf.cpp:84
uint32_t Tell()
Definition: reader_lcf.cpp:228
void ReadString(std::string &ref, size_t size)
Definition: reader_lcf.cpp:186
@ FromCurrent
Definition: reader_lcf.h:85
void Read(void *ptr, size_t size, size_t nmemb)
Definition: reader_lcf.cpp:47
void WriteInt(int val)
Definition: writer_lcf.cpp:51
void Write(const void *ptr, size_t size, size_t nmemb)
Definition: writer_lcf.cpp:24
std::string Decode(const std::string &str_to_encode)
Definition: writer_lcf.cpp:129
RootXmlHandler(S &ref, const char *const name)
const char *const name
void StartElement(XmlReader &stream, const char *name, const char **)
static void WriteLcf(const S &obj, LcfWriter &stream)
static void MakeTagMap()
static tag_map_type tag_map
static const Field< S > * fields[]
static void WriteXml(const S &obj, XmlWriter &stream)
static field_map_type field_map
static void ReadLcf(S &obj, LcfReader &stream)
std::map< int, const Field< S > * > field_map_type
static int LcfSize(const S &obj, LcfWriter &stream)
static const char *const name
static void MakeFieldMap()
static void BeginXml(S &obj, XmlReader &stream)
IDReaderT< S, IDChecker< S >::value > IDReader
std::map< const char *const, const Field< S > *, StringComparator > tag_map_type
const char *const name
XmlHandler * handler
void StartElement(XmlReader &stream, const char *name, const char **)
WrapperXmlHandler(const char *const name, XmlHandler *handler)
static void Read(T &ref, const std::string &data)
void SetHandler(XmlHandler *handler)
Definition: reader_xml.cpp:80
void Error(const char *fmt,...)
Definition: reader_xml.cpp:59
void BeginElement(const std::string &name)
Definition: writer_xml.cpp:161
void EndElement(const std::string &name)
Definition: writer_xml.cpp:177
void WriteInt(int val)
Definition: writer_xml.cpp:137
void Write(const T &val)
RPG::Database data
Definition: data.cpp:14
RPG::System & system
Definition: data.cpp:31
Definition: rpg_actor.h:26
int LcfSize(const S &obj, LcfWriter &) const
void WriteLcf(const S &obj, LcfWriter &stream) const
int LcfSize(const S &obj, LcfWriter &stream) const
bool IsDefault(const S &a, const S &b) const
void ParseXml(S &, const std::string &) const
void BeginXml(S &, XmlReader &) const
bool IsDefault(const S &, const S &) const
void ReadLcf(S &, LcfReader &, uint32_t) const
void WriteXml(const S &, XmlWriter &) const
void WriteLcf(const S &, LcfWriter &) const
int LcfSize(const S &, LcfWriter &) const
bool isPresentIfDefault(bool db_is2k3) const
S struct_type
bool present_if_default
bool is2k3
const char *const name
virtual void BeginXml(S &obj, XmlReader &stream) const =0
virtual void WriteXml(const S &obj, XmlWriter &stream) const =0
virtual bool IsDefault(const S &obj, const S &ref) const =0
virtual void ParseXml(S &obj, const std::string &data) const =0
Field(int id, const char *name, bool present_if_default, bool is2k3)
virtual void WriteLcf(const S &obj, LcfWriter &stream) const =0
virtual void ReadLcf(S &obj, LcfReader &stream, uint32_t length) const =0
virtual int LcfSize(const S &obj, LcfWriter &stream) const =0
static yes check(type_check< int C::*, &C::ID > *)
static no check(...)
static const bool value
static void ReadID(S &, LcfReader &)
static int IDSize(const S &)
static void WriteID(const S &, LcfWriter &)
static void ReadIDXml(S &, const char **)
static void WriteXmlTag(const S &, const std::string &name, XmlWriter &stream)
static void ReadIDXml(S &obj, const char **atts)
static void WriteID(const S &obj, LcfWriter &stream)
static void WriteXmlTag(const S &obj, const std::string &name, XmlWriter &stream)
static int IDSize(const S &obj)
static void ReadID(S &obj, LcfReader &stream)
static const uint32_t value
static void WriteXml(const int32_t &ref, XmlWriter &stream)
static int LcfSize(const int32_t &ref, LcfWriter &)
static void WriteLcf(const int32_t &ref, LcfWriter &stream)
static void ReadLcf(int32_t &ref, LcfReader &stream, uint32_t length)
static void ParseXml(int32_t &ref, const std::string &data)
static void ParseXml(std::string &ref, const std::string &data)
static void ReadLcf(std::string &ref, LcfReader &stream, uint32_t length)
static void WriteLcf(const std::string &ref, LcfWriter &stream)
static void WriteXml(const std::string &ref, XmlWriter &stream)
static int LcfSize(const std::string &ref, LcfWriter &stream)
static void WriteXml(const std::vector< T > &ref, XmlWriter &stream)
static void ReadLcf(std::vector< T > &ref, LcfReader &stream, uint32_t length)
static void WriteLcf(const std::vector< T > &ref, LcfWriter &stream)
static void ParseXml(std::vector< T > &ref, const std::string &data)
static int LcfSize(const std::vector< T > &ref, LcfWriter &)
static void WriteXml(const T &ref, XmlWriter &stream)
static void ReadLcf(T &ref, LcfReader &stream, uint32_t length)
static void WriteLcf(const T &ref, LcfWriter &stream)
static void ParseXml(T &ref, const std::string &data)
static int LcfSize(const T &, LcfWriter &)
static int LcfSize(const T &ref, LcfWriter &stream)
static void WriteXml(const T &ref, XmlWriter &stream)
static void ReadLcf(T &ref, LcfReader &stream, uint32_t length)
static void WriteLcf(const T &ref, LcfWriter &stream)
static void BeginXml(T &ref, XmlReader &stream)
bool IsDefault(const S &a, const S &b) const
void WriteXml(const S &, XmlWriter &) const
SizeField(const std::vector< T > S::*ref, int id, bool present_if_default, bool is2k3)
void BeginXml(S &, XmlReader &) const
const std::vector< T > S::* ref
int LcfSize(const S &obj, LcfWriter &stream) const
void WriteLcf(const S &obj, LcfWriter &stream) const
void ReadLcf(S &, LcfReader &stream, uint32_t length) const
void ParseXml(S &, const std::string &) const
bool operator()(const char *const &lhs, const char *const &rhs) const
static const Category::Index value
Definition: reader_struct.h:58
static int LcfSize(const T &ref, LcfWriter &stream)
static void WriteXml(const T &ref, XmlWriter &stream)
static void ParseXml(T &, const std::string &)
static void WriteLcf(const T &ref, LcfWriter &stream)
static void BeginXml(T &ref, XmlReader &stream)
static void ReadLcf(T &ref, LcfReader &stream, uint32_t length)
static int LcfSize(const T &ref, LcfWriter &stream)
static void BeginXml(T &, XmlReader &)
static void WriteXml(const T &ref, XmlWriter &stream)
static void ReadLcf(T &ref, LcfReader &stream, uint32_t length)
static void ParseXml(T &ref, const std::string &data)
static void WriteLcf(const T &ref, LcfWriter &stream)
static void BeginXml(T &ref, XmlReader &stream)
static void WriteLcf(const T &ref, LcfWriter &stream)
static int LcfSize(const T &ref, LcfWriter &stream)
static void WriteXml(const T &ref, XmlWriter &stream)
static void ParseXml(T &, const std::string &)
static void ReadLcf(T &ref, LcfReader &stream, uint32_t length)
static void BeginXml(T &ref, XmlReader &stream)
static void WriteLcf(const T &ref, LcfWriter &stream)
static int LcfSize(const T &ref, LcfWriter &stream)
static void ReadLcf(T &ref, LcfReader &stream, uint32_t)
static void WriteXml(const T &ref, XmlWriter &stream)
static void ParseXml(T &, const std::string &)
static void BeginXml(std::vector< T > &ref, XmlReader &stream)
static int LcfSize(const std::vector< T > &ref, LcfWriter &stream)
static void ParseXml(std::vector< T > &, const std::string &)
static void ReadLcf(std::vector< T > &ref, LcfReader &stream, uint32_t)
static void WriteLcf(const std::vector< T > &ref, LcfWriter &stream)
static void WriteXml(const std::vector< T > &ref, XmlWriter &stream)
void BeginXml(S &obj, XmlReader &stream) const
TypedField(T S::*ref, int id, const char *name, bool present_if_default, bool is2k3)
void ReadLcf(S &obj, LcfReader &stream, uint32_t length) const
void ParseXml(S &obj, const std::string &data) const
void WriteXml(const S &obj, XmlWriter &stream) const
int LcfSize(const S &obj, LcfWriter &stream) const
bool IsDefault(const S &a, const S &b) const
void WriteLcf(const S &obj, LcfWriter &stream) const