Free Electron
Serializable.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #pragma once
8 
9 namespace fe
10 {
11 namespace ext
12 {
13 
14 class Serializable
15 {
16 public:
17  virtual String serialize(void) const { return ""; };
18  virtual void deserialize(String input) {};
19 
20  virtual bool operator==(const Serializable &other) const
21  {
22  if (typeid(*this) != typeid(other))
23  return false;
24 
25  // Slow but all-encompasing comparison.
26  return serialize() == other.serialize();
27  };
28 };
29 
30 template <class T>
31 class FE_DL_EXPORT InfoSerializable : public BaseType::Info
32 {
33 public:
34  IWORD output(std::ostream &ostrm, void *instance, t_serialMode mode) override;
35  void input(std::istream &istrm, void *instance, t_serialMode mode) override;
36  String print(void *instance) override;
37  void construct(void *instance) override;
38  IWORD iosize(void) override;
39 };
40 
41 template <class T>
42 class FE_DL_EXPORT InfoSp : public BaseType::Info
43 {
44 public:
45  IWORD output(std::ostream &ostrm, void *instance, t_serialMode mode) override
46  {
47  if (mode == e_binary)
48  {
49  // For proper implementation we need protobuf.
50  feX("Binary serialization not implemented.");
51  }
52  else
53  {
54  return c_ascii;
55  }
56 
57  };
58  void input(std::istream &istrm, void *instance, t_serialMode mode) override
59  {
60  if (mode == e_binary)
61  {
62  // For proper implementation we need protobuf.
63  feX("Binary serialization not implemented.");
64  }
65  };
66  String print(void *instance) override { return ""; };
67  void construct(void *instance) override {};
68  IWORD iosize(void) override { return 0; };
69 };
70 
71 template <class T>
72 class FE_DL_EXPORT InfoSerializableArray : public BaseType::Info
73 {
74 public:
75  IWORD output(std::ostream &ostrm, void *instance, t_serialMode mode) override;
76  void input(std::istream &istrm, void *instance, t_serialMode mode) override;
77  String print(void *instance) override;
78  void construct(void *instance) override;
79  IWORD iosize(void) override;
80 
81 private:
82  InfoIWORD helpIWORD;
83 };
84 
85 template <class T>
86 IWORD InfoSerializableArray<T>::output(std::ostream &ostrm, void *instance, t_serialMode mode)
87 {
88  if (mode == e_binary)
89  {
90  // For proper implementation we need protobuf.
91  feX("Binary serialization not implemented.");
92  }
93  else
94  {
95  // Cast to array pointer so we can iterate it.
96  Array<T> *pArray = (Array<T> *)instance;
97 
98  // Write array size so it can be read correctly.
99  IWORD size = pArray->size();
100  helpIWORD.output(ostrm, &size, t_serialMode::e_ascii);
101  // Write array size delimiter.
102  ostrm << "|";
103 
104  for (unsigned int i = 0; i < size; i++)
105  {
106  // Serialize to string.
107  String output = pArray->at(i).serialize();
108 
109  // Write string with quotes and null terminate it.
110  ostrm << "\"" << output.c_str() << "\"";// << '\0';
111  }
112 
113  return c_ascii;
114  }
115 };
116 
117 template <class T>
118 void InfoSerializableArray<T>::input(std::istream &istrm, void *instance, t_serialMode mode)
119 {
120  if (mode == e_binary)
121  {
122  // For proper implementation we need protobuf.
123  feX("Binary serialization not implemented.");
124  }
125  else
126  {
127  // Cast to array and empty it.
128  Array<T> *pArray = (Array<T> *)instance;
129  pArray->empty();
130 
131  // Read array size so we can read in the correct number of elements.
132  IWORD size;
133  helpIWORD.input(istrm, &size, t_serialMode::e_ascii);
134  // Skip array size delimter.
135  istrm.ignore(1);
136 
137  // Read in specified number of array elements.
138  for (unsigned int i = 0; i < size; i++)
139  {
140  // Read chars into string until we hit null character.
141  std::string str;
142  char c;
143  while (istrm.get(c))
144  {
145  if (c == '\0')
146  {
147  break;
148  }
149  str.push_back(c);
150  }
151 
152  // Remove quotes.
153  String input(str.c_str());
154  input = input.parse();
155 
156  // Deserialize string.
157  T item;
158  item.deserialize(input);
159 
160  // Add it to array.
161  pArray->push_back(item);
162  }
163  }
164 };
165 
166 template <class T>
167 String InfoSerializableArray<T>::print(void *instance)
168 {
169  Array<T> *pArray = (Array<T> *)instance;
170  IWORD size = pArray->size();
171 
172  String s = "";
173 
174  for (unsigned int i = 0; i < size; i++)
175  {
176  s.cat(" <%s>", pArray->at(i).serialize().c_str());
177  }
178  return s;
179 };
180 
181 template <class T>
182 IWORD InfoSerializableArray<T>::iosize(void)
183 {
184  return sizeof(T);
185 };
186 
187 template <class T>
188 void InfoSerializableArray<T>::construct(void *instance){};
189 
190 template <class T>
191 IWORD InfoSerializable<T>::output(std::ostream &ostrm, void *instance, t_serialMode mode)
192 {
193  if (mode == e_binary)
194  {
195  // Code below is not reliable for network transmission. It only works if the
196  // encoding/decoding code is compiled the same as it's sensitive to byte size, endianness,
197  // and memory layout. For proper implementation we need protobuf.
198  feX("Binary serialization not implemented.");
199 
200  // // Cast data to bytes.
201  // char *buffer = reinterpret_cast<char *>(instance);
202  // // Write bytes.
203  // ostrm.write(buffer, iosize());
204  // return iosize();
205  }
206  else
207  {
208  // Serialize to string.
209  String output = ((T *)instance)->serialize();
210 
211  // Write string with quotes.
212  ostrm << "\"" << output.c_str() << "\"";
213 
214  return c_ascii;
215  }
216 };
217 
218 template <class T>
219 void InfoSerializable<T>::input(std::istream &istrm, void *instance, t_serialMode mode)
220 {
221  if (mode == e_binary)
222  {
223  // Code below is not reliable for network transmission. It only works if the
224  // encoding/decoding code is compiled the same as it's sensitive to byte size, endianness,
225  // and memory layout. For proper implementation we need protobuf.
226  feX("Binary serialization not implemented.");
227 
228  // // Create byte buffer to read data into.
229  // char buffer[iosize()];
230  // // Read in bytes.
231  // istrm.read(buffer, iosize());
232  // // Cast the binary data to the target class and write it to the pointer target.
233  // *(T *)instance = *reinterpret_cast<T *>(buffer);
234  }
235  else
236  {
237  // Read chars into string until we hit null character.
238  std::string str;
239  char c;
240  while (istrm.get(c))
241  {
242  if (c == '\0')
243  {
244  break;
245  }
246  str.push_back(c);
247  }
248 
249  // Remove quotes.
250  String input(str.c_str());
251  input = input.parse();
252 
253  // Deserialize string.
254  ((T *)instance)->deserialize(input);
255  }
256 };
257 
258 template <class T>
259 String InfoSerializable<T>::print(void *instance)
260 {
261  String s = "";
262  s.cat(" <%s>", ((T *)instance)->serialize().c_str());
263  return s;
264 };
265 
266 template <class T>
267 IWORD InfoSerializable<T>::iosize(void)
268 {
269  return sizeof(T);
270 };
271 
272 template <class T>
273 void InfoSerializable<T>::construct(void *instance){};
274 
275 } // namespace ext
276 } // namespace fe
kernel
Definition: namespace.dox:3
BWORD operator==(const DualString &s1, const DualString &s2)
Compare two DualString&#39;s.
Definition: DualString.h:208