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 
164  int peek_byte() { return in.peek(); }
165 
167  bool debug() const { return debug_; }
168 
170  void reset();
171 
172  private:
173 
179  template <class T, class M>
180  void shared_unpack(T& e) {
181  char i;
182  unpack("Shared::flag", i);
183  switch (i) {
184  case 'd': // definition
185  e = T::deserialize(*this);
186  if (shared_map_) (*shared_map_)[e.get()] = nodes_.size();
187  nodes_.emplace_back(e.get());
188  break;
189  case 'r': // reference
190  {
191  casadi_int k;
192  unpack("Shared::reference", k);
193  UniversalNodeOwner& t = nodes_.at(k);
194  e = T::create(static_cast<M*>(t.get()));
195  }
196  break;
197  default:
198  casadi_assert_dev(false);
199  }
200  }
201 
207  void assert_decoration(char e);
208 
210  std::vector<UniversalNodeOwner> nodes_;
211  std::unordered_map<void*, casadi_int>* shared_map_ = nullptr;
213  std::istream& in;
215  bool debug_;
217  bool set_up_ = false;
218  };
219 
227  class CASADI_EXPORT SerializingStream {
228  friend class DeserializingStream;
229  public:
231  SerializingStream(std::ostream& out);
232  SerializingStream(std::ostream& out, const Dict& opts);
233 
234  // @{
238  void pack(const Sparsity& e);
239  void pack(const MX& e);
240  void pack(const SXElem& e);
241  void pack(const Linsol& e);
242  template <class T>
243  void pack(const Matrix<T>& e) {
244  e.serialize(*this);
245  }
246  void pack(const Function& e);
247  void pack(const Importer& e);
248  void pack(const Resource& e);
249  void pack(const Fmu& e);
250  void pack(const Slice& e);
251  void pack(const GenericType& e);
252  void pack(std::istream& s);
253  void pack(int e);
254 #if SIZE_MAX != UINT_MAX || defined(__EMSCRIPTEN__) || defined(__POWERPC__)
255  void pack(unsigned int e);
256 #endif
257  void pack(bool e);
258  void pack(casadi_int e);
259  void pack(size_t e);
260  void pack(double e);
261  void pack(const std::string& e);
262  void pack(char e);
263  template <class T>
264  void pack(const std::vector<T>& e) {
265  decorate('V');
266  pack(static_cast<casadi_int>(e.size()));
267  for (auto&& i : e) pack(i);
268  }
269  template <class K, class V>
270  void pack(const std::map<K, V>& e) {
271  decorate('D');
272  pack(static_cast<casadi_int>(e.size()));
273  for (const auto & i : e) {
274  pack(i.first);
275  pack(i.second);
276  }
277  }
278  template <class A, class B>
279  void pack(const std::pair<A, B>& e) {
280  decorate('p');
281  pack(e.first);
282  pack(e.second);
283  }
284  template <class T>
285  void pack(const std::string& descr, const T& e) {
286  if (debug_) pack(descr);
287  pack(e);
288  }
289  template <class T>
290  void pack(const std::string& descr, T& e) {
291  if (debug_) pack(descr);
292  pack(e);
293  }
295 
296  void version(const std::string& name, int v);
297 
299  void reset();
300 
301  private:
307  void decorate(char e);
308 
314  template <class T>
315  void shared_pack(const T& e) {
316  auto it = shared_map_.find(e.get());
317  if (it==shared_map_.end()) {
318  // Not found
319  pack("Shared::flag", 'd'); // definition
320  e.serialize(*this);
321  casadi_int r = shared_map_.size();
322  shared_map_[e.get()] = r;
323  if (nodes_) nodes_->emplace_back(e.get());
324  } else {
325  pack("Shared::flag", 'r'); // reference
326  pack("Shared::reference", it->second);
327  }
328  }
329 
331  std::unordered_map<void*, casadi_int> shared_map_;
332  std::vector<UniversalNodeOwner>* nodes_ = nullptr;
334  std::ostream& out;
336  bool debug_;
337  };
338 
339  template <>
340  CASADI_EXPORT void DeserializingStream::unpack(std::vector<bool>& e);
341 
342 } // namespace casadi
343 
344 #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)
bool debug() const
Whether the stream was written in debug-decoration mode.
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.