serializing_stream.hpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #ifndef CASADI_SERIALIZING_STREAM_HPP
27 #define CASADI_SERIALIZING_STREAM_HPP
28 
29 #include <set>
30 #include <sstream>
31 #include <unordered_map>
32 #include <cstdint>
33 #include <climits>
34 
35 namespace casadi {
36  class Slice;
37  class Linsol;
38  class Sparsity;
39  class Function;
40  class MX;
41  class SXElem;
42  class GenericType;
43  class Importer;
44  class Resource;
45  class Fmu;
46  class SharedObject;
47  class SharedObjectInternal;
48  class SXNode;
49  class SerializingStream;
51  public:
52  UniversalNodeOwner() = delete;
54  UniversalNodeOwner(UniversalNodeOwner&& rhs) noexcept;
60  void* get() { return node; }
61  private:
62  void* node;
63  bool is_sx;
64  };
65  typedef std::map<std::string, GenericType> Dict;
66 
73  class CASADI_EXPORT DeserializingStream {
74  friend class SerializingStream;
75  public:
77  DeserializingStream(std::istream &in_s);
79 
81 
87  void unpack(Sparsity& e);
88  void unpack(MX& e);
89  void unpack(SXElem& e);
90  void unpack(Linsol& e);
91  template <class T>
92  void unpack(Matrix<T>& e) {
93  e = Matrix<T>::deserialize(*this);
94  }
95  void unpack(Function& e);
96  void unpack(Importer& e);
97  void unpack(Resource& e);
98  void unpack(Fmu& e);
99  void unpack(GenericType& e);
100  void unpack(std::ostream& s);
101  void unpack(Slice& e);
102  void unpack(int& e);
103 
104 #if SIZE_MAX != UINT_MAX || defined(__EMSCRIPTEN__)
105  void unpack(unsigned int& e);
106 #endif
107  void unpack(bool& e);
108  void unpack(casadi_int& e);
109  void unpack(size_t& e);
110  void unpack(std::string& e);
111  void unpack(double& e);
112  void unpack(char& e);
113  template <class T>
114  void unpack(std::vector<T>& e) {
115  assert_decoration('V');
116  casadi_int s;
117  unpack(s);
118  e.resize(s);
119  for (T& i : e) unpack(i);
120  }
121 
122  template <class K, class V>
123  void unpack(std::map<K, V>& e) {
124  assert_decoration('D');
125  casadi_int s;
126  unpack(s);
127  e.clear();
128  for (casadi_int i=0;i<s;++i) {
129  K k;
130  V v;
131  unpack(k);
132  unpack(v);
133  e[k] = v;
134  }
135  }
136 
137  template <class A, class B>
138  void unpack(std::pair<A, B>& e) {
139  assert_decoration('p');
140  unpack(e.first);
141  unpack(e.second);
142  }
143 
144  template <class T>
145  void unpack(const std::string& descr, T& e) {
146  if (debug_) {
147  std::string d;
148  unpack(d);
149  casadi_assert(d==descr, "Mismatch: '" + descr + "' expected, got '" + d + "'.");
150  }
151  unpack(e);
152  }
154 
155  void version(const std::string& name, int v);
156  int version(const std::string& name);
157  int version(const std::string& name, int min, int max);
158 
159  void connect(SerializingStream & s);
160  void reset();
161 
162  private:
163 
169  template <class T, class M>
170  void shared_unpack(T& e) {
171  char i;
172  unpack("Shared::flag", i);
173  switch (i) {
174  case 'd': // definition
175  e = T::deserialize(*this);
176  if (shared_map_) (*shared_map_)[e.get()] = nodes_.size();
177  nodes_.emplace_back(e.get());
178  break;
179  case 'r': // reference
180  {
181  casadi_int k;
182  unpack("Shared::reference", k);
183  UniversalNodeOwner& t = nodes_.at(k);
184  e = T::create(static_cast<M*>(t.get()));
185  }
186  break;
187  default:
188  casadi_assert_dev(false);
189  }
190  }
191 
197  void assert_decoration(char e);
198 
200  std::vector<UniversalNodeOwner> nodes_;
201  std::unordered_map<void*, casadi_int>* shared_map_ = nullptr;
203  std::istream& in;
205  bool debug_;
206  };
207 
215  class CASADI_EXPORT SerializingStream {
216  friend class DeserializingStream;
217  public:
219  SerializingStream(std::ostream& out);
220  SerializingStream(std::ostream& out, const Dict& opts);
221 
222  // @{
226  void pack(const Sparsity& e);
227  void pack(const MX& e);
228  void pack(const SXElem& e);
229  void pack(const Linsol& e);
230  template <class T>
231  void pack(const Matrix<T>& e) {
232  e.serialize(*this);
233  }
234  void pack(const Function& e);
235  void pack(const Importer& e);
236  void pack(const Resource& e);
237  void pack(const Fmu& e);
238  void pack(const Slice& e);
239  void pack(const GenericType& e);
240  void pack(std::istream& s);
241  void pack(int e);
242 #if SIZE_MAX != UINT_MAX || defined(__EMSCRIPTEN__)
243  void pack(unsigned int e);
244 #endif
245  void pack(bool e);
246  void pack(casadi_int e);
247  void pack(size_t e);
248  void pack(double e);
249  void pack(const std::string& e);
250  void pack(char e);
251  template <class T>
252  void pack(const std::vector<T>& e) {
253  decorate('V');
254  pack(static_cast<casadi_int>(e.size()));
255  for (auto&& i : e) pack(i);
256  }
257  template <class K, class V>
258  void pack(const std::map<K, V>& e) {
259  decorate('D');
260  pack(static_cast<casadi_int>(e.size()));
261  for (const auto & i : e) {
262  pack(i.first);
263  pack(i.second);
264  }
265  }
266  template <class A, class B>
267  void pack(const std::pair<A, B>& e) {
268  decorate('p');
269  pack(e.first);
270  pack(e.second);
271  }
272  template <class T>
273  void pack(const std::string& descr, const T& e) {
274  if (debug_) pack(descr);
275  pack(e);
276  }
277  template <class T>
278  void pack(const std::string& descr, T& e) {
279  if (debug_) pack(descr);
280  pack(e);
281  }
283 
284  void version(const std::string& name, int v);
285 
286  void connect(DeserializingStream & s);
287  void reset();
288 
289  private:
295  void decorate(char e);
296 
302  template <class T>
303  void shared_pack(const T& e) {
304  auto it = shared_map_.find(e.get());
305  if (it==shared_map_.end()) {
306  // Not found
307  pack("Shared::flag", 'd'); // definition
308  e.serialize(*this);
309  casadi_int r = shared_map_.size();
310  shared_map_[e.get()] = r;
311  if (nodes_) nodes_->emplace_back(e.get());
312  } else {
313  pack("Shared::flag", 'r'); // reference
314  pack("Shared::reference", it->second);
315  }
316  }
317 
319  std::unordered_map<void*, casadi_int> shared_map_;
320  std::vector<UniversalNodeOwner>* nodes_ = nullptr;
322  std::ostream& out;
324  bool debug_;
325  };
326 
327  template <>
328  CASADI_EXPORT void DeserializingStream::unpack(std::vector<bool>& e);
329 
330 } // namespace casadi
331 
332 #endif // CASADI_SERIALIZING_STREAM_HPP
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
DeserializingStream(const DeserializingStream &)=delete
void unpack(std::pair< A, B > &e)
void unpack(std::vector< T > &e)
void unpack(std::map< K, V > &e)
void unpack(const std::string &descr, T &e)
Interface to binary FMU.
Definition: fmu.hpp:61
Function object.
Definition: function.hpp:60
Generic data type, can hold different types such as bool, casadi_int, std::string etc.
Importer.
Definition: importer.hpp:86
Linear solver.
Definition: linsol.hpp:55
MX - Matrix expression.
Definition: mx.hpp:92
Sparse matrix class. SX and DM are specializations.
Definition: matrix_decl.hpp:99
void serialize(std::ostream &stream) const
Serialize an object.
static Matrix< Scalar > deserialize(std::istream &stream)
Build Sparsity from serialization.
RAII class for reading from a zip file.
Definition: resource.hpp:44
The basic scalar symbolic class of CasADi.
Definition: sx_elem.hpp:75
Internal node class for SX.
Definition: sx_node.hpp:49
Helper class for Serialization.
void pack(const std::string &descr, const T &e)
void pack(const std::map< K, V > &e)
void pack(const std::pair< A, B > &e)
void pack(const std::string &descr, T &e)
void pack(const std::vector< T > &e)
void pack(const Matrix< T > &e)
Class representing a Slice.
Definition: slice.hpp:48
General sparsity class.
Definition: sparsity.hpp:106
UniversalNodeOwner & operator=(const UniversalNodeOwner &other)=delete
UniversalNodeOwner(const UniversalNodeOwner &)=delete
The casadi namespace.
Definition: archiver.cpp:28
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.