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 Fmu;
45  class SharedObject;
46  class SharedObjectInternal;
47  class SXNode;
48  class SerializingStream;
50  public:
51  UniversalNodeOwner() = delete;
54  UniversalNodeOwner(SharedObjectInternal* obj);
55  UniversalNodeOwner(SXNode* obj);
59  void* get() { return node; }
60  private:
61  void* node;
62  bool is_sx;
63  };
64  typedef std::map<std::string, GenericType> Dict;
65 
72  class CASADI_EXPORT DeserializingStream {
73  friend class SerializingStream;
74  public:
76  DeserializingStream(std::istream &in_s);
78 
80 
86  void unpack(Sparsity& e);
87  void unpack(MX& e);
88  void unpack(SXElem& e);
89  void unpack(Linsol& e);
90  template <class T>
91  void unpack(Matrix<T>& e) {
92  e = Matrix<T>::deserialize(*this);
93  }
94  void unpack(Function& e);
95  void unpack(Importer& e);
96  void unpack(Fmu& e);
97  void unpack(GenericType& e);
98  void unpack(std::ostream& s);
99  void unpack(Slice& e);
100  void unpack(int& e);
101 
102 #if SIZE_MAX != UINT_MAX || defined(__EMSCRIPTEN__)
103  void unpack(unsigned int& e);
104 #endif
105  void unpack(bool& e);
106  void unpack(casadi_int& e);
107  void unpack(size_t& e);
108  void unpack(std::string& e);
109  void unpack(double& e);
110  void unpack(char& e);
111  template <class T>
112  void unpack(std::vector<T>& e) {
113  assert_decoration('V');
114  casadi_int s;
115  unpack(s);
116  e.resize(s);
117  for (T& i : e) unpack(i);
118  }
119 
120  template <class K, class V>
121  void unpack(std::map<K, V>& e) {
122  assert_decoration('D');
123  casadi_int s;
124  unpack(s);
125  e.clear();
126  for (casadi_int i=0;i<s;++i) {
127  K k;
128  V v;
129  unpack(k);
130  unpack(v);
131  e[k] = v;
132  }
133  }
134 
135  template <class A, class B>
136  void unpack(std::pair<A, B>& e) {
137  assert_decoration('p');
138  unpack(e.first);
139  unpack(e.second);
140  }
141 
142  template <class T>
143  void unpack(const std::string& descr, T& e) {
144  if (debug_) {
145  std::string d;
146  unpack(d);
147  casadi_assert(d==descr, "Mismatch: '" + descr + "' expected, got '" + d + "'.");
148  }
149  unpack(e);
150  }
152 
153  void version(const std::string& name, int v);
154  int version(const std::string& name);
155  int version(const std::string& name, int min, int max);
156 
158  void reset();
159 
160  private:
161 
167  template <class T, class M>
168  void shared_unpack(T& e) {
169  char i;
170  unpack("Shared::flag", i);
171  switch (i) {
172  case 'd': // definition
173  e = T::deserialize(*this);
174  if (shared_map_) (*shared_map_)[e.get()] = nodes_.size();
175  nodes_.emplace_back(e.get());
176  break;
177  case 'r': // reference
178  {
179  casadi_int k;
180  unpack("Shared::reference", k);
181  UniversalNodeOwner& t = nodes_.at(k);
182  e = T::create(static_cast<M*>(t.get()));
183  }
184  break;
185  default:
186  casadi_assert_dev(false);
187  }
188  }
189 
195  void assert_decoration(char e);
196 
198  std::vector<UniversalNodeOwner> nodes_;
199  std::unordered_map<void*, casadi_int>* shared_map_ = nullptr;
201  std::istream& in;
203  bool debug_;
204  };
205 
213  class CASADI_EXPORT SerializingStream {
214  friend class DeserializingStream;
215  public:
217  SerializingStream(std::ostream& out);
218  SerializingStream(std::ostream& out, const Dict& opts);
219 
220  // @{
224  void pack(const Sparsity& e);
225  void pack(const MX& e);
226  void pack(const SXElem& e);
227  void pack(const Linsol& e);
228  template <class T>
229  void pack(const Matrix<T>& e) {
230  e.serialize(*this);
231  }
232  void pack(const Function& e);
233  void pack(const Importer& e);
234  void pack(const Fmu& e);
235  void pack(const Slice& e);
236  void pack(const GenericType& e);
237  void pack(std::istream& s);
238  void pack(int e);
239 #if SIZE_MAX != UINT_MAX || defined(__EMSCRIPTEN__)
240  void pack(unsigned int e);
241 #endif
242  void pack(bool e);
243  void pack(casadi_int e);
244  void pack(size_t e);
245  void pack(double e);
246  void pack(const std::string& e);
247  void pack(char e);
248  template <class T>
249  void pack(const std::vector<T>& e) {
250  decorate('V');
251  pack(static_cast<casadi_int>(e.size()));
252  for (auto&& i : e) pack(i);
253  }
254  template <class K, class V>
255  void pack(const std::map<K, V>& e) {
256  decorate('D');
257  pack(static_cast<casadi_int>(e.size()));
258  for (const auto & i : e) {
259  pack(i.first);
260  pack(i.second);
261  }
262  }
263  template <class A, class B>
264  void pack(const std::pair<A, B>& e) {
265  decorate('p');
266  pack(e.first);
267  pack(e.second);
268  }
269  template <class T>
270  void pack(const std::string& descr, const T& e) {
271  if (debug_) pack(descr);
272  pack(e);
273  }
274  template <class T>
275  void pack(const std::string& descr, T& e) {
276  if (debug_) pack(descr);
277  pack(e);
278  }
280 
281  void version(const std::string& name, int v);
282 
284  void reset();
285 
286  private:
292  void decorate(char e);
293 
299  template <class T>
300  void shared_pack(const T& e) {
301  auto it = shared_map_.find(e.get());
302  if (it==shared_map_.end()) {
303  // Not found
304  pack("Shared::flag", 'd'); // definition
305  e.serialize(*this);
306  casadi_int r = shared_map_.size();
307  shared_map_[e.get()] = r;
308  if (nodes_) nodes_->emplace_back(e.get());
309  } else {
310  pack("Shared::flag", 'r'); // reference
311  pack("Shared::reference", it->second);
312  }
313  }
314 
316  std::unordered_map<void*, casadi_int> shared_map_;
317  std::vector<UniversalNodeOwner>* nodes_ = nullptr;
319  std::ostream& out;
321  bool debug_;
322  };
323 
324  template <>
325  CASADI_EXPORT void DeserializingStream::unpack(std::vector<bool>& e);
326 
327 } // namespace casadi
328 
329 #endif // CASADI_SERIALIZING_STREAM_HPP
Helper class for Serialization.
void unpack(std::string &e)
DeserializingStream(std::istream &in_s)
Constructor.
void unpack(Importer &e)
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
void unpack(casadi_int &e)
DeserializingStream(const DeserializingStream &)=delete
int version(const std::string &name)
int version(const std::string &name, int min, int max)
void unpack(std::pair< A, B > &e)
void unpack(std::ostream &s)
void unpack(std::vector< T > &e)
void unpack(Function &e)
void unpack(GenericType &e)
void unpack(std::map< K, V > &e)
void unpack(const std::string &descr, T &e)
void version(const std::string &name, int v)
void connect(SerializingStream &s)
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:84
Sparse matrix class. SX and DM are specializations.
Definition: matrix_decl.hpp:92
static Matrix< Scalar > deserialize(std::istream &stream)
Build Sparsity from serialization.
std::string serialize() const
Serialize.
Helper class for Serialization.
void pack(const std::string &descr, const T &e)
void pack(const GenericType &e)
void version(const std::string &name, int v)
void pack(const std::map< K, V > &e)
void pack(const std::pair< A, B > &e)
void pack(const std::string &e)
void pack(casadi_int e)
SerializingStream(std::ostream &out)
Constructor.
void pack(const Sparsity &e)
Serializes an object to the output stream.
void pack(const std::string &descr, T &e)
void pack(const Importer &e)
void pack(const std::vector< T > &e)
void pack(const Function &e)
void pack(std::istream &s)
void pack(const Linsol &e)
void pack(const Slice &e)
SerializingStream(std::ostream &out, const Dict &opts)
void pack(const Fmu &e)
void connect(DeserializingStream &s)
void pack(const Matrix< T > &e)
void pack(const SXElem &e)
void pack(const MX &e)
Class representing a Slice.
Definition: slice.hpp:48
General sparsity class.
Definition: sparsity.hpp:99
UniversalNodeOwner(UniversalNodeOwner &&rhs) noexcept
UniversalNodeOwner & operator=(const UniversalNodeOwner &other)=delete
UniversalNodeOwner(SharedObjectInternal *obj)
UniversalNodeOwner(SXNode *obj)
UniversalNodeOwner(const UniversalNodeOwner &)=delete
UniversalNodeOwner & operator=(UniversalNodeOwner &&other) noexcept
The casadi namespace.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.