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;
55  UniversalNodeOwner(SharedObjectInternal* obj);
56  UniversalNodeOwner(SXNode* obj);
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 
80  void setup();
81 
83 
89  void unpack(Sparsity& e);
90  void unpack(MX& e);
91  void unpack(SXElem& e);
92  void unpack(Linsol& e);
93  template <class T>
94  void unpack(Matrix<T>& e) {
95  e = Matrix<T>::deserialize(*this);
96  }
97  void unpack(Function& e);
98  void unpack(Importer& e);
99  void unpack(Resource& e);
100  void unpack(Fmu& e);
101  void unpack(GenericType& e);
102  void unpack(std::ostream& s);
103  void unpack(Slice& e);
104  void unpack(int& e);
105 
106 #if SIZE_MAX != UINT_MAX || defined(__EMSCRIPTEN__) || defined(__POWERPC__)
107  void unpack(unsigned int& e);
108 #endif
109  void unpack(bool& e);
110  void unpack(casadi_int& e);
111  void unpack(size_t& e);
112  void unpack(std::string& e);
113  void unpack(double& e);
114  void unpack(char& e);
115  template <class T>
116  void unpack(std::vector<T>& e) {
117  assert_decoration('V');
118  casadi_int s;
119  unpack(s);
120  e.resize(s);
121  for (T& i : e) unpack(i);
122  }
123 
124  template <class K, class V>
125  void unpack(std::map<K, V>& e) {
126  assert_decoration('D');
127  casadi_int s;
128  unpack(s);
129  e.clear();
130  for (casadi_int i=0;i<s;++i) {
131  K k;
132  V v;
133  unpack(k);
134  unpack(v);
135  e[k] = v;
136  }
137  }
138 
139  template <class A, class B>
140  void unpack(std::pair<A, B>& e) {
141  assert_decoration('p');
142  unpack(e.first);
143  unpack(e.second);
144  }
145 
146  template <class T>
147  void unpack(const std::string& descr, T& e) {
148  if (debug_) {
149  std::string d;
150  unpack(d);
151  casadi_assert(d==descr, "Mismatch: '" + descr + "' expected, got '" + d + "'.");
152  }
153  unpack(e);
154  }
156 
157  void version(const std::string& name, int v);
158  int version(const std::string& name);
159  int version(const std::string& name, int min, int max);
160 
162  void reset();
163 
164  private:
165 
171  template <class T, class M>
172  void shared_unpack(T& e) {
173  char i;
174  unpack("Shared::flag", i);
175  switch (i) {
176  case 'd': // definition
177  e = T::deserialize(*this);
178  if (shared_map_) (*shared_map_)[e.get()] = nodes_.size();
179  nodes_.emplace_back(e.get());
180  break;
181  case 'r': // reference
182  {
183  casadi_int k;
184  unpack("Shared::reference", k);
185  UniversalNodeOwner& t = nodes_.at(k);
186  e = T::create(static_cast<M*>(t.get()));
187  }
188  break;
189  default:
190  casadi_assert_dev(false);
191  }
192  }
193 
199  void assert_decoration(char e);
200 
202  std::vector<UniversalNodeOwner> nodes_;
203  std::unordered_map<void*, casadi_int>* shared_map_ = nullptr;
205  std::istream& in;
207  bool debug_;
209  bool set_up_ = false;
210  };
211 
219  class CASADI_EXPORT SerializingStream {
220  friend class DeserializingStream;
221  public:
223  SerializingStream(std::ostream& out);
224  SerializingStream(std::ostream& out, const Dict& opts);
225 
226  // @{
230  void pack(const Sparsity& e);
231  void pack(const MX& e);
232  void pack(const SXElem& e);
233  void pack(const Linsol& e);
234  template <class T>
235  void pack(const Matrix<T>& e) {
236  e.serialize(*this);
237  }
238  void pack(const Function& e);
239  void pack(const Importer& e);
240  void pack(const Resource& e);
241  void pack(const Fmu& e);
242  void pack(const Slice& e);
243  void pack(const GenericType& e);
244  void pack(std::istream& s);
245  void pack(int e);
246 #if SIZE_MAX != UINT_MAX || defined(__EMSCRIPTEN__) || defined(__POWERPC__)
247  void pack(unsigned int e);
248 #endif
249  void pack(bool e);
250  void pack(casadi_int e);
251  void pack(size_t e);
252  void pack(double e);
253  void pack(const std::string& e);
254  void pack(char e);
255  template <class T>
256  void pack(const std::vector<T>& e) {
257  decorate('V');
258  pack(static_cast<casadi_int>(e.size()));
259  for (auto&& i : e) pack(i);
260  }
261  template <class K, class V>
262  void pack(const std::map<K, V>& e) {
263  decorate('D');
264  pack(static_cast<casadi_int>(e.size()));
265  for (const auto & i : e) {
266  pack(i.first);
267  pack(i.second);
268  }
269  }
270  template <class A, class B>
271  void pack(const std::pair<A, B>& e) {
272  decorate('p');
273  pack(e.first);
274  pack(e.second);
275  }
276  template <class T>
277  void pack(const std::string& descr, const T& e) {
278  if (debug_) pack(descr);
279  pack(e);
280  }
281  template <class T>
282  void pack(const std::string& descr, T& e) {
283  if (debug_) pack(descr);
284  pack(e);
285  }
287 
288  void version(const std::string& name, int v);
289 
291  void reset();
292 
293  private:
299  void decorate(char e);
300 
306  template <class T>
307  void shared_pack(const T& e) {
308  auto it = shared_map_.find(e.get());
309  if (it==shared_map_.end()) {
310  // Not found
311  pack("Shared::flag", 'd'); // definition
312  e.serialize(*this);
313  casadi_int r = shared_map_.size();
314  shared_map_[e.get()] = r;
315  if (nodes_) nodes_->emplace_back(e.get());
316  } else {
317  pack("Shared::flag", 'r'); // reference
318  pack("Shared::reference", it->second);
319  }
320  }
321 
323  std::unordered_map<void*, casadi_int> shared_map_;
324  std::vector<UniversalNodeOwner>* nodes_ = nullptr;
326  std::ostream& out;
328  bool debug_;
329  };
330 
331  template <>
332  CASADI_EXPORT void DeserializingStream::unpack(std::vector<bool>& e);
333 
334 } // namespace casadi
335 
336 #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(Resource &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:92
Sparse matrix class. SX and DM are specializations.
Definition: matrix_decl.hpp:99
static Matrix< Scalar > deserialize(std::istream &stream)
Build Sparsity from serialization.
std::string serialize() const
Serialize.
RAII class for reading from a zip file.
Definition: resource.hpp:44
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 Resource &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:106
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.
Definition: archiver.hpp:32
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.