Elementa v8.0.0
Minimalistic library for any C++ application (C++11 and up)
Loading...
Searching...
No Matches
serializers.h
Go to the documentation of this file.
1
3#include "elementa/license.inc"
4#include "elementa/checks.inc"
5
6#ifndef ELEMENTA_BASE_SERIAL_CHANNELS_SERIALIZERS_H
7#define ELEMENTA_BASE_SERIAL_CHANNELS_SERIALIZERS_H
8
9#include <type_traits>
10#include <utility>
14#include "elementa/base/serial_channels.h"
15
16namespace elementa
17{
18
19namespace base
20{
21
22
62/* ======================================================================
63
64 MISCELLANEOUS DEFINITIONS
65
66 (since there are classes in here, we do not use \name to group because
67 classes are not affected by \name)
68
69========================================================================= */
70
71/* ***************************************************************************
72
73 Class: SzerError
74
75*****************************************************************************/
76
78
82class SzerError: public Exc
83{
84 public:
85
86 SzerError(const std::string & explanation):
87 Exc{std::string{"Serializer error. "} + explanation}
88 {}
89
91};
92
93
94
95/* ======================================================================
96
97 SERIALIZERS
98
99========================================================================= */
100
101/* ***************************************************************************
102
103 Base template class: Serializer
104
105*****************************************************************************/
106
108
185template <class Sble,
186 class ReturnDeserType = void,
187 class ReturnSerType = void>// it's more common to need ReturnDeserType
189{
190 public:
191
193 using SType = Sble;
194
196 using RDeserType = Sble;
197
199 using RSerType = Sble;
200
201
203
206 virtual ReturnSerType ser(OutSerCh & chout, const Sble & obj)
208
210
214 virtual ReturnDeserType deser(InSerCh & chin, Sble & obj)
216
217};
218
219
220/* ======================================================================
221
222 SERIALIZABLES
223
224========================================================================= */
225
226
227/* ***************************************************************************
228
229 Base template class: Serializable
230
231*****************************************************************************/
232
234
248template <class DeserReturnType = void,
249 class SerReturnType = void>
251{
252 public:
253
255
256 virtual SerReturnType serme(OutSerCh & chout) const
258
260 virtual DeserReturnType deserme(InSerCh & chin)
262
263};
264
265
266/* ***************************************************************************
267
268 Operators: << , >>
269
270*****************************************************************************/
271
273
275template <class DeserReturnType,
276 class SerReturnType>
279{
280 o.serme(chout);
281 return(chout);
282}
283
284
286
288template <class DeserReturnType,
289 class SerReturnType>
292{
293 o.deserme(chin);
294 return(chin);
295}
296
297
298/* ***************************************************************************
299
300 Template class (adapter): ClassSzer_, ClassSzer
301
302*****************************************************************************/
303
305template <class Sble, class DeserReturnType, class SerReturnType>
306class ClassSzer_ final: public Serializer<Sble,DeserReturnType,SerReturnType>
307{
308 public:
309
310 SerReturnType ser(OutSerCh & chout, const Sble & obj)
311 { return(obj.serme(chout)); }
312
313 DeserReturnType deser(InSerCh & chin, Sble & obj)
314 { return(obj.deserme(chin)); }
315};
316
317
319template <class Sble, class SerReturnType>
320class ClassSzer_<Sble,void,SerReturnType> final:
321 public Serializer<Sble,void,SerReturnType>
322{
323 public:
324
325 SerReturnType ser(OutSerCh & chout, const Sble & obj)
326 { return(obj.serme(chout)); }
327
328 void deser(InSerCh & chin, Sble & obj)
329 { obj.deserme(chin); }
330};
331
333template <class Sble, class DeserReturnType>
334class ClassSzer_<Sble,DeserReturnType,void> final:
335 public Serializer<Sble,DeserReturnType,void>
336{
337 public:
338
339 void ser(OutSerCh & chout, const Sble & obj)
340 { obj.serme(chout); }
341
342 DeserReturnType deser(InSerCh & chin, Sble & obj)
343 { return(obj.deserme(chin)); }
344};
345
347template <class Sble>
348class ClassSzer_<Sble,void,void> final: public Serializer<Sble,void,void>
349{
350 public:
351
352 void ser(OutSerCh & chout, const Sble & obj)
353 { obj.serme(chout); }
354
355 void deser(InSerCh & chin, Sble & obj)
356 { obj.deserme(chin); }
357};
358
359
361
368template <class Sble, class DeserReturnType = void, class SerReturnType = void>
369using ClassSzer = ClassSzer_<Sble,DeserReturnType,SerReturnType>;
370
371
372
373/* ======================================================================
374
375 COMMON SERIALIZERS
376
377========================================================================= */
378
379
380/* ***************************************************************************
381
382 Class: Szer_Char
383
384*****************************************************************************/
385
387class Szer_Char: public Serializer<char>
388{
389 public:
390
391 void ser(OutSerCh & chout, const char & c)
392 { chout.put(c); serch_isgood(chout,ELE_CODE_PLACE); }
393
394 void deser(InSerCh & chin, char & c)
397 chin.get(c); }
398
399};
400
401
402/* ***************************************************************************
403
404 Class: Szer_String
405
406*****************************************************************************/
407
409
426class Szer_String: public Serializer<std::string>
427{
428 public:
429
431
432 Szer_String(SerChSize size = 0, char c = ' '): size_{size},
433 c_{c}
434 {}
435
437
442 void ser(OutSerCh & chout, const std::string & s);
443
445
452 void deser(InSerCh & chin, std::string & s);
453
455 SerChSize sersize(void) const { return(size_); }
456
457 private:
458
459 const SerChSize size_;
460 const char c_;
461};
462
463
464/* ***************************************************************************
465
466 Class template: Szer_NatBin
467
468*****************************************************************************/
469
471
491template <typename NatType>
492class Szer_NatBin: public Serializer<NatType>
493{
494 public:
495
497 Szer_NatBin(SerChSize size = sizeof(NatType)): size_{size}
498 {}
499
501 void ser(OutSerCh & chout, const NatType & obj);
502
504 void deser(InSerCh & chin, NatType & obj);
505
507 SerChSize sersize(void) const { return(size_); }
508
509 private:
510
511 const SerChSize size_;
512
513 // Static assert at the end due to a bug in doxygen that stops generating
514 // anything else when this is found.
515 static_assert(std::is_integral<NatType>::value &&
516 !std::is_signed<NatType>::value,
517 "Szer_NatBin instantiated with a non-integral or signed type");
518};
519
520
521/* ***************************************************************************
522
523 Class: Szer_IntText
524
525*****************************************************************************/
526
528
540class Szer_IntText: public Serializer<LongestInt>
541{
542 public:
543
545 Szer_IntText(SerChSize size = sizeof(LongestInt)):size_{size}
546 {}
547
549 void ser(OutSerCh & chout, const LongestInt & obj);
550
552 void deser(InSerCh & chin, LongestInt & obj);
553
555 SerChSize sersize(void) const { return(size_); }
556
557 private:
558
559 const SerChSize size_;
560};
561
562
563/* ***************************************************************************
564
565 Class: Szer_RealText
566
567*****************************************************************************/
568
570
582class Szer_RealText: public Serializer<LongestReal>
583{
584 public:
585
587 Szer_RealText(SerChSize size = sizeof(LongestReal)): size_{size}
588 {}
589
591 void ser(OutSerCh & chout, const LongestReal & obj);
592
594 void deser(InSerCh & chin, LongestReal & obj);
595
597 SerChSize sersize(void) const { return(size_); }
598
599 private:
600
601 const SerChSize size_;
602};
603
604
605/* ***************************************************************************
606
607 Class: Szer_StringToken
608
609*****************************************************************************/
610
612
636class Szer_StringToken: public Serializer<std::string,int>
637{
638 public:
639
642 kSeparators,
643 kNonSeparators,
644 kMultiComment,
645 kUniComment,
646 kNone
647 );
648
650
654 Szer_StringToken(const std::string & multilinecomm = "/* */",
655 const std::string & unilinecomm = "// \n",
656 const std::string & seps = "\n\t \f\r\v\x00");
657
659 void ser(OutSerCh & chout, const std::string & obj);
660
662
664 int deser(InSerCh & chin, std::string & obj);
665
666 private:
667
668 std::string separators_;
669 std::string multilinebeg_;
670 std::string multilineend_;
671 std::string unilinebeg_;
672 std::string unilineend_;
673
674 static void split_marks(const std::string & ms,
675 std::string & beg, std::string & end);
676
677 Type kind_of_begin(char c, int prio = 0);
678};
679
680
681
682/* ===========================================================================
683
684 ========== IMPLEMENTATION OF TEMPLATES ==========
685
686============================================================================= */
687
688/* ***************************************************************************
689
690 Class template: Szer_NatBin
691
692*****************************************************************************/
693
694template <typename NatType>
695void Szer_NatBin<NatType>::ser(OutSerCh & chout, const NatType & obj)
696{
697 NatType rem = obj;
698 if (size_>0) // fixed size
699 {
700 for (SerChSize f = 0; f < size_; ++f)
701 {
702 chout.put(rem & 0xff);
704 rem >>= 8;
705 }
706 if (rem!=0)
707 throw(SzerError{"Serializing too long natural"}.
708 asEXC(ELE_CODE_PLACE));
709 }
710 else // dynamic size
711 {
712 do
713 {
714 chout.put(rem & 0xff);
716 rem >>= 8;
717 } while (rem>0);
718 }
719}
720
721template <typename NatType>
722void Szer_NatBin<NatType>::deser(InSerCh & chin, NatType & obj)
723{
724 obj = 0;
725 if (size_>0) // fixed size
726 {
727 char c;
728 for (SerChSize f = 0; f < size_; ++f)
729 {
732 chin.get(c);
733 obj |= static_cast<NatType>(static_cast<uint8_t>(c)) << (8*f);
734 }
735 }
736 else throw(SzerError{"Deserializing natural in non-fixed size mode"}.
737 asEXC(ELE_CODE_PLACE));
738}
739
740
741 // Serializers
743
744
745} // end namespace base
746
747} // end namespace elementa
748
749#endif
750
#define ELE_CODE_PLACE
Produces a std::string with the place of source where the macro is placed.
Definition: debugging.h:194
virtual Exc & asEXC(const std::string &place, const RTTextWithEnum::Combination &flags={RTTextWith::kAll_}) noexcept
Transform it to be thrown as EXC with the given place and flags.
const char * explanation(void) const noexcept
Return the explanation only. It will live as long as this exception.
Definition: exceptions.h:164
Base class for all errors / exceptions in Elementa. Just derive from it.
Definition: exceptions.h:113
#define ELE_CLASS_EXCOVERRIDE(C)
Shortening macro that must be used inside classes derived from Exc.
Definition: exceptions.h:64
#define ELE_CODE_UNIMPLEMENTED
To throw an unimplemented exception.
Definition: exceptions.h:289
long long LongestInt
Longest signed integral type in the target machine.
long double LongestReal
Longest real type.
Error to throw when the channel is exhausted but it should not be.
Definition: basics.h:552
std::istream InSerCh
"Base class" that represents any input serial channel in Elementa.
Definition: basics.h:334
bool serch_isexhausted(InSerCh &serch, const std::string &place="", const RTTextWithEnum::Combination &flags={RTTextWith::kAll_})
Return TRUE if it is eof or exhausted; then throw if the channel is bad/fail.
std::streamsize SerChSize
Type of the size of any channel.
Definition: basics.h:178
std::ostream OutSerCh
"Base class" that represents any output serial channel in Elementa.
Definition: basics.h:247
void serch_isgood(RootSerCh &serchconst, const std::string &place="", const RTTextWithEnum::Combination &flags={RTTextWith::kAll_})
Throw an exception if the channel is not good; do nothing otherwise.
ELE_CLASS_ENUM(Type, kSeparators, kNonSeparators, kMultiComment, kUniComment, kNone)
Types of tokens that can be de-serialized.
Szer_StringToken(const std::string &multilinecomm="/* */", const std::string &unilinecomm="// \n", const std::string &seps="\n\t \f\r\v\x00")
Constructor associating the szer to some separators.
void ser(OutSerCh &chout, const LongestInt &obj)
Serialization of the object into CHOUT.
int deser(InSerCh &chin, std::string &obj)
Deserializes the next token from CHIN.
Sble RDeserType
To access the ReturnDeserType type parameter of this type.
Definition: serializers.h:196
void deser(InSerCh &chin, LongestReal &obj)
Deserializes the object from CHIN.
Szer_NatBin(SerChSize size=sizeof(NatType))
Constructor for fixed size (SIZE > 0) or dynamic size (SIZE == 0).
Definition: serializers.h:497
void ser(OutSerCh &chout, const char &c)
Serializes an object, writing the resulting chars into CHOUT.
Definition: serializers.h:391
Szer_String(SerChSize size=0, char c=' ')
Constructor both for fixed (SIZE>0) and dynamic sized (SIZE==0) strings.
Definition: serializers.h:432
void deser(InSerCh &chin, char &c)
Deserializes an object from a sequence of chars in CHIN.
Definition: serializers.h:394
virtual DeserReturnType deserme(InSerCh &chin)
Method to deserialize the object from CHOUT.
Definition: serializers.h:260
void ser(OutSerCh &chout, const std::string &s)
Serialization of a string into CHOUT.
SerChSize sersize(void) const
Return the size for which the serializer was created.
Definition: serializers.h:507
Sble RSerType
To access the ReturnSerType type parameter of this type.
Definition: serializers.h:199
virtual ReturnSerType ser(OutSerCh &chout, const Sble &obj)
Serializes an object, writing the resulting chars into CHOUT.
Definition: serializers.h:206
void deser(InSerCh &chin, std::string &s)
Deserializes the string from CHIN.
Szer_IntText(SerChSize size=sizeof(LongestInt))
Constructor for fixed size (SIZE > 0) or dynamic size (SIZE == 0).
Definition: serializers.h:545
Sble SType
To access the Sble type parameter of this type.
Definition: serializers.h:193
Szer_RealText(SerChSize size=sizeof(LongestReal))
Constructor.
Definition: serializers.h:587
SerChSize sersize(void) const
Return the size for which the serializer was created.
Definition: serializers.h:455
SerChSize sersize(void) const
Return the size for which the serializer was created.
Definition: serializers.h:555
void deser(InSerCh &chin, LongestInt &obj)
Deserializes the object from CHIN.
virtual ReturnDeserType deser(InSerCh &chin, Sble &obj)
Deserializes an object from a sequence of chars in CHIN.
Definition: serializers.h:214
void ser(OutSerCh &chout, const LongestReal &obj)
Serialization of the object into CHOUT.
virtual SerReturnType serme(OutSerCh &chout) const
Method to serialize the object into CHOUT.
Definition: serializers.h:256
SerChSize sersize(void) const
Return the size for which the serializer was created.
Definition: serializers.h:597
void ser(OutSerCh &chout, const std::string &obj)
Serialization of the object into CHOUT.
Base class for any object that includes an implicit serializer.
Definition: serializers.h:251
Base abstract class / interface for any serializer.
Definition: serializers.h:189
Serializer of a single char. Not very useful, but sometimes it is needed.
Definition: serializers.h:388
Serializer of integer numbers as text in fixed or non-fixed size.
Definition: serializers.h:541
Serializer of natural numbers in fixed or non-fixed size.
Definition: serializers.h:493
Serializer of real numbers as text in fixed or dynamic size.
Definition: serializers.h:583
Serializer of std::string into fixed or non-fixed size.
Definition: serializers.h:427
Serializer of a std::string as a token (useful for lexers).
Definition: serializers.h:637
Base class for all errors thrown by serializers.
Definition: serializers.h:83
InSerCh & operator>>(InSerCh &chin, Serializable< DeserReturnType, SerReturnType > &o)
Operator for deserializing Serializable objects directly from a channel.
Definition: serializers.h:290
OutSerCh & operator<<(OutSerCh &chout, const Serializable< DeserReturnType, SerReturnType > &o)
Operator for serializing Serializable objects directly on a channel.
Definition: serializers.h:277
void ser(OutSerCh &chout, const NatType &obj)
Serialization of the object into CHOUT.
Definition: serializers.h:695
ClassSzer_< Sble, DeserReturnType, SerReturnType > ClassSzer
Objects of this class act as Serializer's for Serializable objects.
Definition: serializers.h:369
void deser(InSerCh &chin, NatType &obj)
Deserializes the number from CHIN.
Definition: serializers.h:722