serializer.cpp
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 #include "function.hpp"
27 #include "serializer.hpp"
28 #include "serializing_stream.hpp"
29 #include "slice.hpp"
30 #include "linsol.hpp"
31 #include "importer.hpp"
32 #include "generic_type.hpp"
33 #include "filesystem_impl.hpp"
34 #include <iomanip>
35 
36 namespace casadi {
37 
39  SerializerBase(std::unique_ptr<std::ostream>(new std::stringstream()), opts) {
40  }
41 
42  FileSerializer::FileSerializer(const std::string& fname, const Dict& opts) :
44  Filesystem::ofstream_ptr(fname, std::ios_base::binary | std::ios::out),
45  opts) {
46  }
47 
48  SerializerBase::SerializerBase(std::unique_ptr<std::ostream> stream, const Dict& opts) :
49  sstream_(std::move(stream)),
50  serializer_(new SerializingStream(*sstream_, opts)) {
51  }
52 
54  switch (type) {
55  case SERIALIZED_SPARSITY: return "sparsity";
56  case SERIALIZED_MX: return "mx";
57  case SERIALIZED_MX_v1: return "mx_v1";
58  case SERIALIZED_DM: return "dm";
59  case SERIALIZED_SX: return "sx";
60  case SERIALIZED_SX_v1: return "sx_v1";
61  case SERIALIZED_LINSOL: return "linsol";
62  case SERIALIZED_FUNCTION: return "function";
63  case SERIALIZED_GENERICTYPE: return "generictype";
64  case SERIALIZED_INT: return "int";
65  case SERIALIZED_DOUBLE: return "double";
66  case SERIALIZED_STRING: return "string";
67  case SERIALIZED_SPARSITY_VECTOR: return "sparsity_vector";
68  case SERIALIZED_MX_VECTOR: return "mx_vector";
69  case SERIALIZED_MX_VECTOR_v1: return "mx_vector_v1";
70  case SERIALIZED_DM_VECTOR: return "dm_vector";
71  case SERIALIZED_SX_VECTOR: return "sx_vector";
72  case SERIALIZED_SX_VECTOR_v1: return "sx_vector_v1";
73  case SERIALIZED_LINSOL_VECTOR: return "linsol_vector";
74  case SERIALIZED_FUNCTION_VECTOR: return "function_vector";
75  case SERIALIZED_GENERICTYPE_VECTOR: return "generictype_vector";
76  case SERIALIZED_INT_VECTOR: return "int_vector";
77  case SERIALIZED_DOUBLE_VECTOR: return "double_vector";
78  case SERIALIZED_STRING_VECTOR: return "string_vector";
79  default: casadi_error("Unknown type" + str(type));
80  }
81  }
82 
84  }
85 
86  std::string StringSerializer::encode() {
87  std::string ret = static_cast<std::stringstream*>(sstream_.get())->str();
88  static_cast<std::stringstream*>(sstream_.get())->str("");
89  sstream_->clear();
90  return ret;
91  }
92  void StringDeserializer::decode(const std::string& string) {
93  casadi_assert(dstream_->peek() == std::char_traits<char>::eof(),
94  "StringDeserializer::decode does not apply: current string not fully consumed yet.");
95  static_cast<std::stringstream*>(dstream_.get())->str(string);
96  dstream_->clear(); // reset error flags
97  deserializer_->setup();
98  }
99 
102 
103  DeserializerBase::DeserializerBase(std::unique_ptr<std::istream> stream) :
104  dstream_(std::move(stream)),
105  deserializer_(new DeserializingStream(*dstream_)) {
106  }
107 
108  FileDeserializer::FileDeserializer(const std::string& fname) :
109  DeserializerBase(Filesystem::ifstream_ptr(fname, std::ios_base::binary | std::ios::in)) {
110  if ((dstream_->rdstate() & std::ifstream::failbit) != 0) {
111  casadi_error("Could not open file '" + fname + "' for reading.");
112  }
113  }
114 
115  StringDeserializer::StringDeserializer(const std::string& string) :
116  DeserializerBase(std::unique_ptr<std::istream>(
117  new std::stringstream(string))) {
118  }
119 
123 
125  return *serializer_;
126  }
127 
129  casadi_assert(dstream_->peek() != std::char_traits<char>::eof(),
130  "Deserializer reached end of stream. Nothing left to unpack.");
131  return *deserializer_;
132  }
133 
135  char type;
136  deserializer().unpack(type);
137  return static_cast<SerializerBase::SerializationType>(type);
138  }
139 
140  void SerializerBase::pack(const MX& e) {
141  serializer().pack(static_cast<char>(SERIALIZED_MX));
143  serializer().pack(e);
144  }
145  void SerializerBase::pack(const std::vector<MX>& e) {
146  serializer().pack(static_cast<char>(SERIALIZED_MX_VECTOR));
148  serializer().pack(e);
149  }
150  void SerializerBase::pack(const SX& e) {
151  serializer().pack(static_cast<char>(SERIALIZED_SX));
153  serializer().pack(e);
154  }
155  void SerializerBase::pack(const std::vector<SX>& e) {
156  serializer().pack(static_cast<char>(SERIALIZED_SX_VECTOR));
158  serializer().pack(e);
159  }
161  std::vector<MX> sorted;
162  deserializer().unpack(sorted);
163  MX ret;
164  deserializer().unpack(ret);
165  return ret;
166  }
168  std::vector<SX> sorted;
169  deserializer().unpack(sorted);
170  SX ret;
171  deserializer().unpack(ret);
172  return ret;
173  }
175  std::vector<MX> sorted;
176  deserializer().unpack(sorted);
177  std::vector<MX> ret;
178  deserializer().unpack(ret);
179  return ret;
180  }
182  std::vector<SX> sorted;
183  deserializer().unpack(sorted);
184  std::vector<SX> ret;
185  deserializer().unpack(ret);
186  return ret;
187  }
189  Function f;
190  deserializer().unpack(f);
191  MX ret;
192  deserializer().unpack(ret);
193  return ret;
194  }
196  Function f;
197  deserializer().unpack(f);
198  SX ret;
199  deserializer().unpack(ret);
200  return ret;
201  }
203  Function f;
204  deserializer().unpack(f);
205  std::vector<MX> ret;
206  deserializer().unpack(ret);
207  return ret;
208  }
210  Function f;
211  deserializer().unpack(f);
212  std::vector<SX> ret;
213  deserializer().unpack(ret);
214  return ret;
215  }
218  if (t==SerializerBase::SerializationType::SERIALIZED_MX_v1) {
219  return blind_unpack_mx_v1();
220  }
221  casadi_assert(t==SerializerBase::SerializationType::SERIALIZED_MX,
222  "Expected to find a '" + SerializerBase::type_to_string(
223  SerializerBase::SerializationType::SERIALIZED_MX)+
224  "', but encountered a '" + SerializerBase::type_to_string(t) + "' instead.");
225  return blind_unpack_mx();
226  }
229  if (t==SerializerBase::SerializationType::SERIALIZED_SX_v1) {
230  return blind_unpack_sx_v1();
231  }
232  casadi_assert(t==SerializerBase::SerializationType::SERIALIZED_SX,
233  "Expected to find a '" + SerializerBase::type_to_string(
234  SerializerBase::SerializationType::SERIALIZED_SX)+
235  "', but encountered a '" + SerializerBase::type_to_string(t) + "' instead.");
236  return blind_unpack_sx();
237  }
240  if (t==SerializerBase::SerializationType::SERIALIZED_MX_VECTOR_v1) {
241  return blind_unpack_mx_vector_v1();
242  }
243  casadi_assert(t==SerializerBase::SerializationType::SERIALIZED_MX_VECTOR, \
244  "Expected to find a '" + SerializerBase::type_to_string(
245  SerializerBase::SerializationType::SERIALIZED_MX_VECTOR)+
246  "', but encountered a '" + SerializerBase::type_to_string(t) + "' instead.");
247  return blind_unpack_mx_vector();
248  }
251  if (t==SerializerBase::SerializationType::SERIALIZED_SX_VECTOR_v1) {
252  return blind_unpack_sx_vector_v1();
253  }
254  casadi_assert(t==SerializerBase::SerializationType::SERIALIZED_SX_VECTOR, \
255  "Expected to find a '" + SerializerBase::type_to_string(\
256  SerializerBase::SerializationType::SERIALIZED_SX_VECTOR)+
257  "', but encountered a '" + SerializerBase::type_to_string(t) + "' instead.");
258  return blind_unpack_sx_vector();
259  }
260 
261 #define SERIALIZE(TYPE, Type, type) \
262  void SerializerBase::pack(const Type& e) { \
263  serializer().pack(static_cast<char>(SERIALIZED_ ## TYPE));\
264  serializer().pack(e); \
265  } \
266  \
267  Type DeserializerBase::blind_unpack_ ## type() { \
268  Type ret;\
269  deserializer().unpack(ret);\
270  return ret;\
271  }\
272  Type DeserializerBase::unpack_ ## type() { \
273  SerializerBase::SerializationType t = pop_type();\
274  casadi_assert(t==SerializerBase::SerializationType::SERIALIZED_ ## TYPE, \
275  "Expected to find a '" + SerializerBase::type_to_string(\
276  SerializerBase::SerializationType::SERIALIZED_ ## TYPE) +\
277  "', but encountered a '" + SerializerBase::type_to_string(t) + "' instead.");\
278  return blind_unpack_ ## type();\
279  }
280 
281 #define SERIALIZE_ALL(TYPE, Type, type)\
282  SERIALIZE(TYPE, Type, type)\
283  SERIALIZE(TYPE ## _VECTOR, std::vector< Type >, type ## _vector)
284 
285 SERIALIZE_ALL(SPARSITY, Sparsity, sparsity)
286 SERIALIZE_ALL(DM, DM, dm)
287 SERIALIZE_ALL(LINSOL, Linsol, linsol)
288 SERIALIZE_ALL(FUNCTION, Function, function)
289 SERIALIZE_ALL(GENERICTYPE, GenericType, generictype)
290 SERIALIZE_ALL(INT, casadi_int, int)
291 SERIALIZE_ALL(DOUBLE, double, double)
292 SERIALIZE_ALL(STRING, std::string , string)
293 
294  void SerializerBase::connect(DeserializerBase & s) {
295  serializer_->connect(*s.deserializer_);
296  }
298  serializer_->reset();
299  }
301  deserializer_->connect(*s.serializer_);
302  }
304  deserializer_->reset();
305  }
306 
307 } // namespace casadi
std::vector< MX > blind_unpack_mx_vector()
Definition: serializer.cpp:174
Matrix< SXElem > blind_unpack_sx_v1()
Definition: serializer.cpp:195
Matrix< SXElem > unpack_sx()
Definition: serializer.cpp:227
std::vector< Matrix< SXElem > > unpack_sx_vector()
Definition: serializer.cpp:249
std::unique_ptr< DeserializingStream > deserializer_
Definition: serializer.hpp:178
DeserializingStream & deserializer()
Definition: serializer.cpp:128
std::vector< MX > blind_unpack_mx_vector_v1()
Definition: serializer.cpp:202
Matrix< SXElem > blind_unpack_sx()
Definition: serializer.cpp:167
std::vector< Matrix< SXElem > > blind_unpack_sx_vector_v1()
Definition: serializer.cpp:209
std::unique_ptr< std::istream > dstream_
Definition: serializer.hpp:177
std::vector< Matrix< SXElem > > blind_unpack_sx_vector()
Definition: serializer.cpp:181
DeserializerBase(std::unique_ptr< std::istream > stream)
Definition: serializer.cpp:103
void connect(SerializerBase &s)
Definition: serializer.cpp:300
SerializerBase::SerializationType pop_type()
Definition: serializer.cpp:134
std::vector< MX > unpack_mx_vector()
Definition: serializer.cpp:238
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
FileDeserializer(const std::string &fname)
Advanced deserialization of CasADi objects.
Definition: serializer.cpp:108
FileSerializer(const std::string &fname, const Dict &opts=Dict())
Advanced serialization of CasADi objects.
Definition: serializer.cpp:42
Filesystem interface.
Function object.
Definition: function.hpp:60
static std::vector< SX > order(const std::vector< SX > &expr)
Definition: function.cpp:1946
Generic data type, can hold different types such as bool, casadi_int, std::string etc.
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
SerializerBase(std::unique_ptr< std::ostream > stream, const Dict &opts=Dict())
Definition: serializer.cpp:48
void connect(DeserializerBase &s)
Definition: serializer.cpp:294
std::unique_ptr< SerializingStream > serializer_
Definition: serializer.hpp:113
void pack(const Sparsity &e)
std::unique_ptr< std::ostream > sstream_
Definition: serializer.hpp:112
static std::string type_to_string(SerializationType type)
Definition: serializer.cpp:53
SerializingStream & serializer()
Definition: serializer.cpp:124
Helper class for Serialization.
void pack(const Sparsity &e)
Serializes an object to the output stream.
General sparsity class.
Definition: sparsity.hpp:106
StringDeserializer(const std::string &string="")
Advanced deserialization of CasADi objects.
Definition: serializer.cpp:115
void decode(const std::string &string)
Sets the string to deserialize objects from.
Definition: serializer.cpp:92
std::string encode()
Returns a string that holds the serialized objects.
Definition: serializer.cpp:86
StringSerializer(const Dict &opts=Dict())
Advanced serialization of CasADi objects.
Definition: serializer.cpp:38
The casadi namespace.
Definition: archiver.cpp:28
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.