liblcf
Loading...
Searching...
No Matches
reader_struct.h
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#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 "lcf/dbstring.h"
24#include "lcf/reader_lcf.h"
25#include "lcf/writer_lcf.h"
26#include "lcf/reader_xml.h"
27#include "lcf/writer_xml.h"
28#include "lcf/rpg/eventpagecondition.h"
29#include "lcf/rpg/trooppagecondition.h"
30#include "lcf/rpg/terrain.h"
31#include "lcf/rpg/equipment.h"
32#include "lcf/rpg/parameters.h"
33#include "lcf/rpg/eventcommand.h"
34#include "lcf/rpg/movecommand.h"
35#include "lcf/rpg/treemap.h"
36#include "lcf/rpg/rect.h"
37#include "lcf/rpg/savepicture.h"
38#include "lcf/rpg/terms.h"
39#include "lcf/rpg/saveeasyrpgtext.h"
40#include "lcf/rpg/saveeasyrpgwindow.h"
41
42namespace lcf {
43
44// Forward declarations
45
46template <class T>
47class Struct;
48
49// Type categories
50
60
61template <class T>
65
66// Do not forget to add new Flags here
67template <> struct TypeCategory<rpg::TroopPageCondition::Flags> { static const Category::Index value = Category::Flags; };
68template <> struct TypeCategory<rpg::EventPageCondition::Flags> { static const Category::Index value = Category::Flags; };
69template <> struct TypeCategory<rpg::Terrain::Flags> { static const Category::Index value = Category::Flags; };
70template <> struct TypeCategory<rpg::SavePicture::Flags> { static const Category::Index value = Category::Flags; };
71template <> struct TypeCategory<rpg::SaveEasyRpgText::Flags> { static const Category::Index value = Category::Flags; };
72template <> struct TypeCategory<rpg::SaveEasyRpgWindow::Flags> { static const Category::Index value = Category::Flags; };
73
74template <> struct TypeCategory<rpg::Equipment> { static const Category::Index value = Category::RawStruct; };
75template <> struct TypeCategory<rpg::EventCommand> { static const Category::Index value = Category::RawStruct; };
76template <> struct TypeCategory<rpg::MoveCommand> { static const Category::Index value = Category::RawStruct; };
77template <> struct TypeCategory<rpg::Parameters> { static const Category::Index value = Category::RawStruct; };
78template <> struct TypeCategory<rpg::TreeMap> { static const Category::Index value = Category::RawStruct; };
79template <> struct TypeCategory<rpg::Rect> { static const Category::Index value = Category::RawStruct; };
80template <> struct TypeCategory<DBString> { static const Category::Index value = Category::RawStruct; };
81
82template <> struct TypeCategory<int8_t> { static const Category::Index value = Category::Primitive; };
83template <> struct TypeCategory<uint8_t> { static const Category::Index value = Category::Primitive; };
84template <> struct TypeCategory<int16_t> { static const Category::Index value = Category::Primitive; };
85template <> struct TypeCategory<uint32_t> { static const Category::Index value = Category::Primitive; };
86template <> struct TypeCategory<int32_t> { static const Category::Index value = Category::Primitive; };
87template <> struct TypeCategory<bool> { static const Category::Index value = Category::Primitive; };
88template <> struct TypeCategory<double> { static const Category::Index value = Category::Primitive; };
89template <> struct TypeCategory<std::string> { static const Category::Index value = Category::Primitive; };
90template <> struct TypeCategory<DBBitArray> { static const Category::Index value = Category::Primitive; };
91
92template <class T>
93struct TypeCategory<std::vector<T>> {
95};
96
100template <class T, Category::Index cat = TypeCategory<T>::value>
101struct TypeReader {};
102
103
108template <class T>
109struct TypeReader<T, Category::Void> {
110 static void ReadLcf(T&, LcfReader& stream, uint32_t length) {
111 stream.Seek(length, LcfReader::FromCurrent);
112 }
113 static void WriteLcf(const T&, LcfWriter&) {
114 }
115 static int LcfSize(const T&, LcfWriter&) {
116 return 0;
117 }
118 static void WriteXml(const T&, XmlWriter&) {
119 }
120 static void BeginXml(T&, XmlReader&) {
121 }
122 static void ParseXml(T& /* ref */, const std::string& /* data */) {
123 //no-op
124 }
125};
126
130template <class T>
131struct RawStruct {
132 static void ReadLcf(T& ref, LcfReader& stream, uint32_t length);
133 static void WriteLcf(const T& ref, LcfWriter& stream);
134 static int LcfSize(const T& ref, LcfWriter& stream);
135 static void WriteXml(const T& ref, XmlWriter& stream);
136 static void BeginXml(T& ref, XmlReader& stream);
137};
138
139template <class T>
141 static void ReadLcf(T& ref, LcfReader& stream, uint32_t length) {
142 RawStruct<T>::ReadLcf(ref, stream, length);
143 }
144 static void WriteLcf(const T& ref, LcfWriter& stream) {
145 RawStruct<T>::WriteLcf(ref, stream);
146 }
147 static int LcfSize(const T& ref, LcfWriter& stream) {
148 return RawStruct<T>::LcfSize(ref, stream);
149 }
150 static void WriteXml(const T& ref, XmlWriter& stream) {
151 RawStruct<T>::WriteXml(ref, stream);
152 }
153 static void BeginXml(T& ref, XmlReader& stream) {
154 RawStruct<T>::BeginXml(ref, stream);
155 }
156 static void ParseXml(T& /* ref */, const std::string& /* data */) {
157 //no-op
158 }
159};
160
164template <class T>
165struct LcfSizeT {
166 static const uint32_t value = sizeof(T);
167};
168
172template <>
173struct LcfSizeT<bool> {
174 static const uint32_t value = 1;
175};
176
180template <class T>
181struct Primitive {
182 static void ReadLcf(T& ref, LcfReader& stream, uint32_t length) {
183 int dif = 0;
184 // FIXME: Bug #174
185 if (length != LcfSizeT<T>::value) {
186 dif = length - LcfSizeT<T>::value;
187 fprintf(stderr, "Reading Primitive of incorrect size %" PRIu32 " (expected %" PRIu32 ") at %" PRIX32 "\n",
188 length, LcfSizeT<T>::value, stream.Tell());
189 }
190
191 stream.Read(ref);
192#ifdef LCF_DEBUG_TRACE
193 DebugPrint(ref);
194#endif
195
196 if (dif != 0) {
197 // Fix incorrect read pointer position
198#ifdef LCF_DEBUG_TRACE
199 printf("Invalid %s at %X\n", typeid(T).name(), stream.Tell());
200#endif
201 stream.Seek(dif, LcfReader::FromCurrent);
202 }
203 }
204 static void WriteLcf(const T& ref, LcfWriter& stream) {
205 stream.Write(ref);
206 }
207 static int LcfSize(const T& /* ref */, LcfWriter& /* stream */) {
208 return LcfSizeT<T>::value;
209 }
210 static void WriteXml(const T& ref, XmlWriter& stream) {
211 stream.Write(ref);
212 }
213 static void ParseXml(T& ref, const std::string& data) {
214 XmlReader::Read(ref, data);
215 }
216 private:
217#ifdef LCF_DEBUG_TRACE
218 template <typename U>
219 static void DebugPrint(U& ref) {
220 std::cout << ref << '\n';
221 }
222 static void DebugPrint(int8_t ref) {
223 std::cout << (int)ref << '\n';
224 }
225 static void DebugPrint(uint8_t ref) {
226 std::cout << (int)ref << '\n';
227 }
228#endif
229};
230
234template <class T>
235struct Primitive<std::vector<T>> {
236 static void ReadLcf(std::vector<T>& ref, LcfReader& stream, uint32_t length) {
237 stream.Read(ref, length);
238#ifdef LCF_DEBUG_TRACE
239 typename std::vector<T>::iterator it;
240 printf(" ");
241 for (it = ref.begin(); it != ref.end(); ++it) {
242 printf("%d, ", static_cast<int>(*it));
243 }
244 printf("\n");
245#endif
246 }
247 static void WriteLcf(const std::vector<T>& ref, LcfWriter& stream) {
248 stream.Write(ref);
249 }
250 static int LcfSize(const std::vector<T>& ref, LcfWriter& /* stream */) {
251 return LcfSizeT<T>::value * ref.size();
252 }
253 static void WriteXml(const std::vector<T>& ref, XmlWriter& stream) {
254 stream.Write(ref);
255 }
256 static void ParseXml(std::vector<T>& ref, const std::string& data) {
257 XmlReader::Read(ref, data);
258 }
259};
260
264template <>
265struct Primitive<int32_t> {
266 static void ReadLcf(int32_t& ref, LcfReader& stream, uint32_t length) {
267 if (length >= 1 && length <= 5) {
268 ref = stream.ReadInt();
269#ifdef LCF_DEBUG_TRACE
270 printf(" %d\n", ref);
271#endif
272 } else {
273 ref = 0;
274#ifdef LCF_DEBUG_TRACE
275 printf("Invalid integer at %X\n", stream.Tell());
276#endif
277 stream.Seek(length, LcfReader::FromCurrent);
278 }
279
280 }
281 static void WriteLcf(const int32_t& ref, LcfWriter& stream) {
282 stream.WriteInt(ref);
283 }
284 static int LcfSize(const int32_t& ref, LcfWriter& /* stream */) {
285 return LcfReader::IntSize(ref);
286 }
287 static void WriteXml(const int32_t& ref, XmlWriter& stream) {
288 stream.WriteInt(ref);
289 }
290 static void ParseXml(int32_t& ref, const std::string& data) {
291 XmlReader::Read(ref, data);
292 }
293};
294
298template <>
299struct Primitive<std::string> {
300 static void ReadLcf(std::string& ref, LcfReader& stream, uint32_t length) {
301 stream.ReadString(ref, length);
302#ifdef LCF_DEBUG_TRACE
303 printf(" %s\n", ref.c_str());
304#endif
305 }
306 static void WriteLcf(const std::string& ref, LcfWriter& stream) {
307 stream.Write(ref);
308 }
309 static int LcfSize(const std::string& ref, LcfWriter& stream) {
310 return stream.Decode(ref).size();
311 }
312 static void WriteXml(const std::string& ref, XmlWriter& stream) {
313 stream.Write(ref);
314 }
315 static void ParseXml(std::string& ref, const std::string& data) {
316 XmlReader::Read(ref, data);
317 }
318};
319
323template <>
324struct Primitive<DBBitArray> {
325 static void ReadLcf(DBBitArray& ref, LcfReader& stream, uint32_t length) {
326 stream.ReadBits(ref, length);
327#ifdef LCF_DEBUG_TRACE
328 printf(" ");
329 for (auto& b: ref) {
330 print("%d", static_cast<int>(b));
331 }
332 printf("\n");
333#endif
334 }
335 static void WriteLcf(const DBBitArray& ref, LcfWriter& stream) {
336 stream.Write(ref);
337 }
338 static int LcfSize(const DBBitArray& ref, LcfWriter& stream) {
339 (void)stream;
340 return ref.size();
341 }
342 static void WriteXml(const DBBitArray& ref, XmlWriter& stream) {
343 stream.Write(ref);
344 }
345 static void ParseXml(DBBitArray& ref, const std::string& data) {
346 XmlReader::Read(ref, data);
347 }
348};
349
350
351
355template <class T>
357 static void ReadLcf(T& ref, LcfReader& stream, uint32_t length) {
358 Primitive<T>::ReadLcf(ref, stream, length);
359 }
360 static void WriteLcf(const T& ref, LcfWriter& stream) {
361 Primitive<T>::WriteLcf(ref, stream);
362 }
363 static int LcfSize(const T& ref, LcfWriter& stream) {
364 return Primitive<T>::LcfSize(ref, stream);
365 }
366 static void WriteXml(const T& ref, XmlWriter& stream) {
367 Primitive<T>::WriteXml(ref, stream);
368 }
369 static void BeginXml(T& /* ref */, XmlReader& /* stream */) {
370 // no-op
371 }
372 static void ParseXml(T& ref, const std::string& data) {
373 Primitive<T>::ParseXml(ref, data);
374 }
375};
376
380template <class S>
381struct Field {
382 typedef S struct_type;
383
384 const char* const name;
385 int id;
387 bool is2k3;
388
389 virtual void ReadLcf(S& obj, LcfReader& stream, uint32_t length) const = 0;
390 virtual void WriteLcf(const S& obj, LcfWriter& stream) const = 0;
391 virtual int LcfSize(const S& obj, LcfWriter& stream) const = 0;
392 virtual bool IsDefault(const S& obj, const S& ref, bool is2k3) const = 0;
393 virtual void WriteXml(const S& obj, XmlWriter& stream) const = 0;
394 virtual void BeginXml(S& obj, XmlReader& stream) const = 0;
395 virtual void ParseXml(S& obj, const std::string& data) const = 0;
396
397 bool isPresentIfDefault(bool db_is2k3) const {
398 if (std::is_same<S,rpg::Terms>::value && db_is2k3 && (id == 0x3 || id == 0x1)) {
399 //Special case - only known fields that are 2k specific and not
400 //written to a 2k3 db if defaulted.
401 return false;
402 }
403 return present_if_default;
404 }
405
408};
409
413template <class S, class T>
414struct TypedField : public Field<S> {
415 T S::*ref;
416
417 void ReadLcf(S& obj, LcfReader& stream, uint32_t length) const {
418 TypeReader<T>::ReadLcf(obj.*ref, stream, length);
419 }
420 void WriteLcf(const S& obj, LcfWriter& stream) const {
421 TypeReader<T>::WriteLcf(obj.*ref, stream);
422 }
423 int LcfSize(const S& obj, LcfWriter& stream) const {
424 return TypeReader<T>::LcfSize(obj.*ref, stream);
425 }
426 void WriteXml(const S& obj, XmlWriter& stream) const {
427 stream.BeginElement(this->name);
428 TypeReader<T>::WriteXml(obj.*ref, stream);
429 stream.EndElement(this->name);
430 }
431 void BeginXml(S& obj, XmlReader& stream) const {
432 TypeReader<T>::BeginXml(obj.*ref, stream);
433 }
434 void ParseXml(S& obj, const std::string& data) const {
435 TypeReader<T>::ParseXml(obj.*ref, data);
436 }
437 bool IsDefault(const S& a, const S& b, bool) const {
438 return a.*ref == b.*ref;
439 }
440
441 TypedField(T S::*ref, int id, const char* name, bool present_if_default, bool is2k3) :
443};
444
449template <typename S, typename T>
450struct DatabaseVersionField : public TypedField<S,T> {
451
452 using TypedField<S,T>::TypedField;
453
454 int LcfSize(const S& obj, LcfWriter& stream) const {
455 //If db version is 0, it's like a "version block" is not present.
456 if ((obj.*(this->ref)) == 0) {
457 return 0;
458 }
459 return TypedField<S,T>::LcfSize(obj, stream);
460 }
461 bool IsDefault(const S& a, const S& b, bool is2k3) const {
462 if (is2k3) {
463 //DB Version always present in 2k3 db
464 return false;
465 }
466 //Only present if not 0 in 2k db.
467 return TypedField<S,T>::IsDefault(a, b, is2k3);
468 }
469};
470
475template <typename S>
476struct EmptyField : public Field<S> {
477
478 using Field<S>::Field;
479
480 void ReadLcf(S& /* obj */, LcfReader& /* stream */, uint32_t /* length */) const { }
481 void WriteLcf(const S& /* obj */, LcfWriter& /* stream */) const { }
482 int LcfSize(const S& /* obj */, LcfWriter& /* stream */) const {
483 //This is always an "empty block"
484 return 0;
485 }
486 void WriteXml(const S& /* obj */, XmlWriter& /* stream */) const { }
487 void BeginXml(S& /* obj */, XmlReader& /* stream */) const { }
488 void ParseXml(S& /* obj */, const std::string& /* data */) const { }
489
490 bool IsDefault(const S& /* a */, const S& /* b */, bool) const {
491 return true;
492 }
493
494};
495
496
497
501template <class S, class T>
502struct SizeField : public Field<S> {
503 const T S::*ref;
504
505 void ReadLcf(S& /* obj */, LcfReader& stream, uint32_t length) const {
506 int32_t dummy;
507 TypeReader<int32_t>::ReadLcf(dummy, stream, length);
508 }
509 void WriteLcf(const S& obj, LcfWriter& stream) const {
510 int size = TypeReader<T>::LcfSize(obj.*ref, stream);
511 TypeReader<int32_t>::WriteLcf(size, stream);
512 }
513 int LcfSize(const S& obj, LcfWriter& stream) const {
514 int size = TypeReader<T>::LcfSize(obj.*ref, stream);
515 return LcfReader::IntSize(size);
516 }
517 void WriteXml(const S& /* obj */, XmlWriter& /* stream */) const {
518 // no-op
519 }
520 void BeginXml(S& /* obj */, XmlReader& /* stream */) const {
521 // no-op
522 }
523 void ParseXml(S& /* obj */, const std::string& /* data */) const {
524 // no-op
525 }
526 bool IsDefault(const S& a, const S& b, bool) const {
527 return (a.*ref).size() == (b.*ref).size();
528 }
529
530 SizeField(const T S::*ref, int id, bool present_if_default, bool is2k3) :
531 Field<S>(id, "", present_if_default, is2k3), ref(ref) {}
532};
533
534
538template <class S, class T>
539struct CountField : public SizeField<S,T> {
540
541 using SizeField<S,T>::SizeField;
542
543 void WriteLcf(const S& obj, LcfWriter& stream) const {
544 int size = (obj.*(this->ref)).size();
545 TypeReader<int32_t>::WriteLcf(size, stream);
546 }
547 int LcfSize(const S& obj, LcfWriter& /* stream */) const {
548 int size = (obj.*(this->ref)).size();
549 return LcfReader::IntSize(size);
550 }
551};
552
556template <class T>
557struct IDChecker {
558 typedef char no;
559 typedef int yes;
560
561 template <typename U, U> struct type_check;
562 template <class C>
564 template <class C>
565 static no check(...);
566
567 static const bool value = sizeof(check<T>(0)) == sizeof(yes);
568};
569
570// ID reader for Struct class
571
572template <class S, bool T>
573struct IDReaderT {
574};
575
576template <class S>
577struct IDReaderT<S, true> {
578 static void ReadID(S& obj, LcfReader& stream) {
579 obj.ID = stream.ReadInt();
580 }
581 static void WriteID(const S& obj, LcfWriter& stream) {
582 stream.WriteInt(obj.ID);
583 }
584 static int IDSize(const S& obj) {
585 return LcfReader::IntSize(obj.ID);
586 }
587 static void WriteXmlTag(const S& obj, const std::string& name, XmlWriter& stream) {
588 stream.BeginElement(name, obj.ID);
589 }
590 static void ReadIDXml(S& obj, const char** atts) {
591 for (int i = 0; atts[i] != NULL && atts[i + 1] != NULL; i += 2) {
592 if (strcmp(atts[i], "id") == 0)
593 obj.ID = atoi(atts[i + 1]);
594 }
595 }
596};
597
598template <class S>
599struct IDReaderT<S, false> {
600 static void ReadID(S& /* obj */, LcfReader& /* stream */) {}
601 static void WriteID(const S& /* obj */, LcfWriter& /* stream */) {}
602 static int IDSize(const S& /* obj */) { return 0; }
603 static void WriteXmlTag(const S& /* obj */, const std::string& name, XmlWriter& stream) {
604 stream.BeginElement(name);
605 }
606 static void ReadIDXml(S& /* obj */, const char** /* atts */) {}
607};
608
610 bool operator() (const char* const& lhs, const char* const& rhs) const {
611 return strcmp(lhs, rhs) < 0;
612 }
613};
614
615// Struct class template
616
617template <class S>
618class Struct {
619private:
620 typedef std::map<int, const Field<S>* > field_map_type;
621 typedef std::map<const char* const, const Field<S>*, StringComparator> tag_map_type;
623 static const Field<S>* fields[];
626 static const char* const name;
627
628 static void MakeFieldMap();
629 static void MakeTagMap();
630
631 template <class T> friend class StructXmlHandler;
632 template <class T> friend class StructVectorXmlHandler;
633 template <class T> friend class StructFieldXmlHandler;
634
635public:
636 static void ReadLcf(S& obj, LcfReader& stream);
637 static void WriteLcf(const S& obj, LcfWriter& stream);
638 static int LcfSize(const S& obj, LcfWriter& stream);
639 static void WriteXml(const S& obj, XmlWriter& stream);
640 static void BeginXml(S& obj, XmlReader& stream);
641
642 static void ReadLcf(std::vector<S>& obj, LcfReader& stream);
643 static void WriteLcf(const std::vector<S>& obj, LcfWriter& stream);
644 static int LcfSize(const std::vector<S>& obj, LcfWriter& stream);
645 static void WriteXml(const std::vector<S>& obj, XmlWriter& stream);
646 static void BeginXml(std::vector<S>& obj, XmlReader& stream);
647};
648
649template <class S>
650std::map<int, const Field<S>* > Struct<S>::field_map;
651
652template <class S>
653std::map<const char* const, const Field<S>*, StringComparator> Struct<S>::tag_map;
654
658template <class T>
660 static void ReadLcf(T& ref, LcfReader& stream, uint32_t /* length */) {
661 Struct<T>::ReadLcf(ref, stream);
662 }
663 static void WriteLcf(const T& ref, LcfWriter& stream) {
664 Struct<T>::WriteLcf(ref, stream);
665 }
666 static int LcfSize(const T& ref, LcfWriter& stream) {
667 return Struct<T>::LcfSize(ref, stream);
668 }
669 static void WriteXml(const T& ref, XmlWriter& stream) {
670 Struct<T>::WriteXml(ref, stream);
671 }
672 static void BeginXml(T& ref, XmlReader& stream) {
673 Struct<T>::BeginXml(ref, stream);
674 }
675 static void ParseXml(T& /* ref */, const std::string& /* data */) {
676 // no-op
677 }
678};
679
680template <class T>
681struct TypeReader<std::vector<T>, Category::Struct> {
682 static void ReadLcf(std::vector<T>& ref, LcfReader& stream, uint32_t /* length */) {
683 Struct<T>::ReadLcf(ref, stream);
684 }
685 static void WriteLcf(const std::vector<T>& ref, LcfWriter& stream) {
686 Struct<T>::WriteLcf(ref, stream);
687 }
688 static int LcfSize(const std::vector<T>& ref, LcfWriter& stream) {
689 return Struct<T>::LcfSize(ref, stream);
690 }
691 static void WriteXml(const std::vector<T>& ref, XmlWriter& stream) {
692 Struct<T>::WriteXml(ref, stream);
693 }
694 static void BeginXml(std::vector<T>& ref, XmlReader& stream) {
695 Struct<T>::BeginXml(ref, stream);
696 }
697 static void ParseXml(std::vector<T>& /* ref */, const std::string& /* data */) {
698 // no-op
699 }
700};
701
702
703
707template <class S>
708class Flags {
709private:
710 static const char* const name;
711 static constexpr size_t num_flags = std::tuple_size<decltype(S::flags)>::value;
712 static const std::array<const char* const, num_flags> flag_names;
713 static const std::array<bool, num_flags> flags_is2k3;
714
715public:
716 static const char* tag(int idx);
717 static int idx(const char* tag);
718
719 static void ReadLcf(S& obj, LcfReader& stream, uint32_t length);
720 static void WriteLcf(const S& obj, LcfWriter& stream);
721 static int LcfSize(const S& obj, LcfWriter& stream);
722 static void WriteXml(const S& obj, XmlWriter& stream);
723 static void BeginXml(S& obj, XmlReader& stream);
724};
725
726template <class S>
727inline const char* Flags<S>::tag(int idx) {
728 return Flags<S>::flag_names[idx];
729}
730
731template <class S>
732inline int Flags<S>::idx(const char* tag) {
733 for (size_t i = 0; i < flag_names.size(); ++i) {
734 if (std::strcmp(flag_names[i], tag) == 0) {
735 return i;
736 }
737 }
738 return -1;
739}
740
744template <class T>
746 static void ReadLcf(T& ref, LcfReader& stream, uint32_t length) {
747 Flags<T>::ReadLcf(ref, stream, length);
748 }
749 static void WriteLcf(const T& ref, LcfWriter& stream) {
750 Flags<T>::WriteLcf(ref, stream);
751 }
752 static int LcfSize(const T& ref, LcfWriter& stream) {
753 return Flags<T>::LcfSize(ref, stream);
754 }
755 static void WriteXml(const T& ref, XmlWriter& stream) {
756 Flags<T>::WriteXml(ref, stream);
757 }
758 static void BeginXml(T& ref, XmlReader& stream) {
759 Flags<T>::BeginXml(ref, stream);
760 }
761 static void ParseXml(T& /* ref */, const std::string& /* data */) {
762 // no-op
763 }
764};
765
769class WrapperXmlHandler : public XmlHandler {
770public:
771 WrapperXmlHandler(const char* const name, XmlHandler* handler) :
773
774 void StartElement(XmlReader& stream, const char* name, const char** /* atts */) {
775 if (strcmp(name, this->name) != 0)
776 stream.Error("Expecting %s but got %s", this->name, name);
777 stream.SetHandler(handler);
778 }
779
780private:
781 const char* const name;
782 XmlHandler* handler;
783};
784
788template <class S>
789class RootXmlHandler : public XmlHandler {
790
791public:
792 RootXmlHandler(S& ref, const char* const name) : ref(ref), name(name) {}
793
794 void StartElement(XmlReader& stream, const char* name, const char** /* atts */) {
795 if (strcmp(name, this->name) != 0)
796 stream.Error("Expecting %s but got %s", this->name, name);
798 }
799
800private:
801 S& ref;
802 const char* const name;
803
804};
805
806} //namespace lcf
807
808#endif
static void BeginXml(S &obj, XmlReader &stream)
static const std::array< const char *const, num_flags > flag_names
static const std::array< bool, num_flags > flags_is2k3
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 constexpr size_t num_flags
static int LcfSize(const S &obj, LcfWriter &stream)
static const char * tag(int idx)
static void WriteLcf(const S &obj, LcfWriter &stream)
static const char *const name
void StartElement(XmlReader &stream, const char *name, const char **)
RootXmlHandler(S &ref, const char *const name)
const char *const name
static void BeginXml(S &obj, XmlReader &stream)
static int LcfSize(const S &obj, LcfWriter &stream)
static void MakeFieldMap()
static const Field< S > * fields[]
static void WriteXml(const S &obj, XmlWriter &stream)
IDReaderT< S, IDChecker< S >::value > IDReader
std::map< const char *const, const Field< S > *, StringComparator > tag_map_type
static tag_map_type tag_map
static void MakeTagMap()
static field_map_type field_map
static void WriteLcf(const S &obj, LcfWriter &stream)
std::map< int, const Field< S > * > field_map_type
static void ReadLcf(S &obj, LcfReader &stream)
static const char *const name
WrapperXmlHandler(const char *const name, XmlHandler *handler)
void StartElement(XmlReader &stream, const char *name, const char **)
const char *const name
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, bool is2k3) const
int LcfSize(const S &, LcfWriter &) const
void WriteXml(const S &, XmlWriter &) const
void ParseXml(S &, const std::string &) const
void ReadLcf(S &, LcfReader &, uint32_t) const
void BeginXml(S &, XmlReader &) const
void WriteLcf(const S &, LcfWriter &) const
bool IsDefault(const S &, const S &, bool) const
virtual void ParseXml(S &obj, const std::string &data) const =0
bool isPresentIfDefault(bool db_is2k3) const
Field(int id, const char *name, bool present_if_default, bool is2k3)
virtual void WriteLcf(const S &obj, LcfWriter &stream) const =0
virtual void BeginXml(S &obj, XmlReader &stream) const =0
virtual bool IsDefault(const S &obj, const S &ref, bool is2k3) const =0
virtual void WriteXml(const S &obj, XmlWriter &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
const char *const name
bool present_if_default
static yes check(type_check< int C::*, &C::ID > *)
static const bool value
static no check(...)
static void WriteID(const S &, LcfWriter &)
static void ReadIDXml(S &, const char **)
static void WriteXmlTag(const S &, const std::string &name, XmlWriter &stream)
static int IDSize(const S &)
static void ReadID(S &, LcfReader &)
static void WriteID(const S &obj, LcfWriter &stream)
static void ReadID(S &obj, LcfReader &stream)
static void WriteXmlTag(const S &obj, const std::string &name, XmlWriter &stream)
static int IDSize(const S &obj)
static void ReadIDXml(S &obj, const char **atts)
static const uint32_t value
static void ReadLcf(DBBitArray &ref, LcfReader &stream, uint32_t length)
static void ParseXml(DBBitArray &ref, const std::string &data)
static void WriteLcf(const DBBitArray &ref, LcfWriter &stream)
static int LcfSize(const DBBitArray &ref, LcfWriter &stream)
static void WriteXml(const DBBitArray &ref, XmlWriter &stream)
static int LcfSize(const int32_t &ref, LcfWriter &)
static void WriteLcf(const int32_t &ref, LcfWriter &stream)
static void ParseXml(int32_t &ref, const std::string &data)
static void ReadLcf(int32_t &ref, LcfReader &stream, uint32_t length)
static void WriteXml(const int32_t &ref, XmlWriter &stream)
static void WriteXml(const std::string &ref, XmlWriter &stream)
static void ReadLcf(std::string &ref, LcfReader &stream, uint32_t length)
static int LcfSize(const std::string &ref, LcfWriter &stream)
static void WriteLcf(const std::string &ref, LcfWriter &stream)
static void ParseXml(std::string &ref, const std::string &data)
static int LcfSize(const std::vector< T > &ref, LcfWriter &)
static void ParseXml(std::vector< T > &ref, const std::string &data)
static void WriteLcf(const std::vector< T > &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 ReadLcf(T &ref, LcfReader &stream, uint32_t length)
static void WriteLcf(const T &ref, LcfWriter &stream)
static int LcfSize(const T &, LcfWriter &)
static void ParseXml(T &ref, const std::string &data)
static void WriteXml(const T &ref, XmlWriter &stream)
static void ReadLcf(T &ref, LcfReader &stream, uint32_t length)
static void WriteXml(const T &ref, XmlWriter &stream)
static void BeginXml(T &ref, XmlReader &stream)
static void WriteLcf(const T &ref, LcfWriter &stream)
static int LcfSize(const T &ref, LcfWriter &stream)
void BeginXml(S &, XmlReader &) const
SizeField(const T S::*ref, int id, bool present_if_default, bool is2k3)
void WriteXml(const S &, XmlWriter &) const
bool IsDefault(const S &a, const S &b, bool) const
void ReadLcf(S &, LcfReader &stream, uint32_t length) const
void ParseXml(S &, const std::string &) const
void WriteLcf(const S &obj, LcfWriter &stream) const
const T S::* ref
int LcfSize(const S &obj, LcfWriter &stream) const
bool operator()(const char *const &lhs, const char *const &rhs) const
static const Category::Index value
static void WriteLcf(const T &ref, LcfWriter &stream)
static int LcfSize(const T &ref, LcfWriter &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 WriteXml(const T &ref, XmlWriter &stream)
static int LcfSize(const T &ref, LcfWriter &stream)
static void BeginXml(T &, XmlReader &)
static void WriteXml(const T &ref, XmlWriter &stream)
static void WriteLcf(const T &ref, LcfWriter &stream)
static void ReadLcf(T &ref, LcfReader &stream, uint32_t length)
static void ParseXml(T &ref, const std::string &data)
static void WriteXml(const T &ref, XmlWriter &stream)
static void ParseXml(T &, const std::string &)
static int LcfSize(const T &ref, LcfWriter &stream)
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 void ParseXml(T &, const std::string &)
static void WriteXml(const T &ref, XmlWriter &stream)
static void WriteLcf(const T &ref, LcfWriter &stream)
static void BeginXml(T &ref, XmlReader &stream)
static int LcfSize(const T &ref, LcfWriter &stream)
static void ReadLcf(T &ref, LcfReader &stream, uint32_t)
static void BeginXml(T &, XmlReader &)
static int LcfSize(const T &, LcfWriter &)
static void WriteLcf(const T &, LcfWriter &)
static void ReadLcf(T &, LcfReader &stream, uint32_t length)
static void ParseXml(T &, const std::string &)
static void WriteXml(const T &, XmlWriter &)
static void WriteLcf(const std::vector< T > &ref, LcfWriter &stream)
static void BeginXml(std::vector< T > &ref, XmlReader &stream)
static void WriteXml(const std::vector< T > &ref, XmlWriter &stream)
static void ReadLcf(std::vector< T > &ref, LcfReader &stream, uint32_t)
static int LcfSize(const std::vector< T > &ref, LcfWriter &stream)
static void ParseXml(std::vector< T > &, const std::string &)
void BeginXml(S &obj, XmlReader &stream) const
TypedField(T S::*ref, int id, const char *name, bool present_if_default, bool is2k3)
void WriteLcf(const S &obj, LcfWriter &stream) const
void ReadLcf(S &obj, LcfReader &stream, uint32_t length) const
void WriteXml(const S &obj, XmlWriter &stream) const
bool IsDefault(const S &a, const S &b, bool) const
int LcfSize(const S &obj, LcfWriter &stream) const
void ParseXml(S &obj, const std::string &data) const