Arduino Libraries
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
serializer.hpp
Go to the documentation of this file.
1 // Author: Mario S. Könz <mskoenz@gmx.net>
2 // Date: 29.05.2013 23:04:33 EDT
3 // File: serializer.hpp
4 
5 /* This program is free software. It comes without any warranty, to
6  * the extent permitted by applicable law. You can redistribute it
7  * and/or modify it under the terms of the Do What The Fuck You Want
8  * To Public License, Version 2, as published by Sam Hocevar. See
9  * http://www.wtfpl.net/ or COPYING for more details. */
10 
11 #ifndef __SERIALIZER_HEADER
12 #define __SERIALIZER_HEADER
13 
14 //~ #define __TYPE_SIZE_CHECK
15 //~ #define __LESS_ZERO
16 
17 #include "archive_enum.hpp"
18 #include "../ustd/type_traits.hpp"
19 #include "../ustd/ard_assert.hpp"
20 #include "../util/byte_operation.hpp"
21 #include "../util/has_serialize.hpp"
22 
23 namespace com {
24  //------------------- implementation -------------------
25  template<typename T, typename Archive>
26  void serialize(Archive & ar, T & t);
27  //------------------- recursively serializes arrays :D -------------------
28  template<typename T, typename Archive, archive_enum type, bool is_an_array> //default == true
29  struct impl_version {
30  static void get(T & t, Archive & ar) {
31  for(uint16_t i = 0; i < sizeof(t)/sizeof(t[0]); ++i) {
32  serialize(ar, t[i]); //<-calls serialize for subarrays
33  }
34  }
35  };
36  template<typename T, typename Archive>
37  struct impl_version<T, Archive, archive_enum::output, false> { //if no serialize, then byte-serialize
38  static void get(T const & t, Archive & ar) {
39  #ifdef __TYPE_SIZE_CHECK
40  ar.write(sizeof(t));
41  #endif //__TYPE_SIZE_CHECK
42  #ifdef __LESS_ZERO
43  uint8_t idx = sizeof(t);
44  while(idx != 0) {
45  if(util::read_byte(t, idx - 1) != 0)
46  break;
47  else
48  --idx;
49  }
50  ar.write(idx);
51  for(uint8_t i = 0; i < idx; ++i)
52  ar.write(util::read_byte(t, i));
53  #else //__LESS_ZERO
54  for(uint8_t i = 0; i < sizeof(t); ++i)
55  ar.write(util::read_byte(t, i));
56  #endif //__LESS_ZERO
57  }
58  };
59  template<typename T, typename Archive>
60  struct impl_version<T, Archive, archive_enum::input, false> {
61  static void get(T & t, Archive & ar) {
62  #ifdef __TYPE_SIZE_CHECK
63  uint8_t exp_size = ar.read();
64  ASSERT(sizeof(t) == exp_size);
65  #endif //__TYPE_SIZE_CHECK
66  #ifdef __LESS_ZERO
67  uint8_t idx = ar.read();
68  for(uint8_t i = 0; i < idx; ++i)
69  util::write_byte(t, i, ar.read());
70  for(uint8_t i = idx; i < sizeof(t); ++i) {
71  util::write_byte(t, i, 0x00);
72  }
73  #else //__LESS_ZERO
74  for(uint8_t i = 0; i < sizeof(t); ++i)
75  util::write_byte(t, i, ar.read());
76  #endif //__LESS_ZERO
77  }
78  };
79 
80  template<typename T, bool has_serialize_tpl, typename Archive> //default == true
82  static void get(Archive & ar, T & t) {
83  t.serialize(ar);
84  }
85  };
86 
87  template<typename T, typename Archive> //has no serialize_tpl
88  struct serialize_helper<T, false, Archive> {
89  static void get(Archive & ar, T & t) {
91  }
92  };
93 
94  template<typename T, typename Archive>
95  void serialize(Archive & ar, T & t) {
97  }
98  //------------------- endian helper for of class -------------------
99  template<typename T>
100  T little_endian(T const & t) { //just mirrors the bytes
101  T res(0);
102 
103  for(uint8_t i = 0; i < sizeof(t); ++i) {
104  res |= ((t >> ((sizeof(t) - i - 1))*8 & 0xFF) << (8 * i));
105  }
106 
107  return res;
108  }
109  //------------------- of class -------------------
110  template<typename D, uint16_t max_buf>
111  class oss_class {
112  public:
113  typedef uint16_t size_type;
115 
116  oss_class(D & data): pos_(0), data(data) {
117  }
118  template<typename T>
119  oss_class & operator&(T & t) {
120  serialize(*this, t);
121  return (*this);
122  }
123  template<typename S>
124  void print(S & os) const {
125  #ifdef __TYPE_SIZE_CHECK
126  size_type sub = 0;
127  #endif //__TYPE_SIZE_CHECK
128 
129  os << F("oss: ");
130  for(size_type i = 0; i < pos_; ++i) {
131  #ifdef __TYPE_SIZE_CHECK
132  if(i == sub) {
133  uint8_t size = data.read(i);
134  os << GREENB << size << NONE << F(" ");
135  sub += size + 1;
136  }
137  else
138  os << data.read(i) << F(" ");
139  #else //__TYPE_SIZE_CHECK
140  os << data.read(i) << F(" ");
141  #endif //__TYPE_SIZE_CHECK
142  }
143  }
144  void write(uint8_t const & in) {
145  ASSERT_MSG(pos_ < max_buf, "buffer_size to small in oss_class::operator<<")
146  data.write(pos_, in);
147  ++(pos_);
148  }
150  return pos_;
151  }
152  private:
153  size_type pos_;
154  D & data;
155  };
156  //------------------- os stream operator -------------------
157  template<typename D, uint16_t max_buf, typename S>
158  S & operator<<(S & os, oss_class<D, max_buf> const & arg) {
159  arg.print(os);
160  return os;
161  }
162 
163  //------------------- if class -------------------
164  template<typename D, uint16_t max_buf>
165  class iss_class {
166  public:
167  typedef uint16_t size_type;
169 
170  iss_class(D & data): pos_(0), data(data) {
171  }
172  template<typename T>
173  iss_class & operator&(T & t) {
174  serialize(*this, t);
175  return (*this);
176  }
177  template<typename S>
178  void print(S & os) const {
179  #ifdef __TYPE_SIZE_CHECK
180  size_type sub = 0;
181  #endif //__TYPE_SIZE_CHECK
182 
183  os << F("iss: ");
184  for(size_type i = 0; i < pos_; ++i) {
185  #ifdef __TYPE_SIZE_CHECK
186  if(i == sub) {
187  uint8_t size = data.read(i);
188  os << REDB << size << NONE << F(" ");
189  sub += size + 1;
190  }
191  else {
192  os << data.read(i) << F(" ");
193  }
194  #else //__TYPE_SIZE_CHECK
195  os << data.read(i) << F(" ");
196  #endif //__TYPE_SIZE_CHECK
197  }
198  }
199  uint8_t read() {
200  ASSERT_MSG(pos_ < max_buf, "buffer_size to small in iss_class::operator<<")
201  return data.read(pos_++);
202  }
204  return pos_;
205  }
206  private:
207  size_type pos_;
208  D & data;
209  };
210  //------------------- os<<stream operator -------------------
211  template<typename D, uint16_t max_buf, typename S>
212  S & operator<<(S & os, iss_class<D, max_buf> const & arg) {
213  arg.print(os);
214  return os;
215  }
216 }//end namespace com
217 #endif //__SERIALIZER_HEADER
static archive_enum const type
Definition: serializer.hpp:168
size_type & pos()
Definition: serializer.hpp:203
void serialize(Archive &ar, T &t)
Definition: serializer.hpp:95
Definition: serializer.hpp:111
static archive_enum const type
Definition: serializer.hpp:114
oss_class(D &data)
Definition: serializer.hpp:116
Definition: serializer.hpp:29
size_type & pos()
Definition: serializer.hpp:149
#define GREENB
Definition: color.hpp:16
#define ASSERT_MSG(exp, msg)
Definition: ard_assert.hpp:34
oss_class & operator&(T &t)
Definition: serializer.hpp:119
T little_endian(T const &t)
Definition: serializer.hpp:100
iss_class(D &data)
Definition: serializer.hpp:170
uint8_t read_byte(T const &t, detail::byte_op_size_type const &pos)
Definition: byte_operation.hpp:25
void print(S &os) const
Definition: serializer.hpp:178
uint16_t size_type
Definition: serializer.hpp:113
uint16_t size_type
Definition: serializer.hpp:167
archive_enum
Definition: archive_enum.hpp:14
#define NONE
Definition: color.hpp:37
void write_byte(T &t, detail::byte_op_size_type const &pos, uint8_t const &in)
Definition: byte_operation.hpp:30
#define REDB
Definition: color.hpp:14
Definition: serializer.hpp:81
#define F(x)
Definition: ustd_generic.hpp:15
void write(uint8_t const &in)
Definition: serializer.hpp:144
iss_class & operator&(T &t)
Definition: serializer.hpp:173
void print(S &os) const
Definition: serializer.hpp:124
Definition: serializer.hpp:165
#define ASSERT(exp)
Definition: ard_assert.hpp:33
uint8_t read()
Definition: serializer.hpp:199