1 /*
2  *    This file is part of CasADi.
3  *
4  *    CasADi -- A symbolic framework for dynamic optimization.
5  *    Copyright (C) 2010-2014 Joel Andersson, Joris Gillis, Moritz Diehl,
6  *                            K.U. 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_SERIALIZER_HPP
27 #define CASADI_SERIALIZER_HPP
28 
29 #include <memory>
30 #include <set>
31 #include <sstream>
32 #include <unordered_map>
33 
34 namespace casadi {
35 
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 DeserializerBase;
45 
46 
47 
48   class CASADI_EXPORT SerializerBase {
49     friend class DeserializerBase;
50   public:
51 #ifndef SWIG
52     SerializerBase(std::unique_ptr<std::ostream> stream, const Dict& opts = Dict());
53 #endif // SWIG
54     ~SerializerBase();
55     void pack(const Sparsity& e);
56     void pack(const MX& e);
57     void pack(const Matrix<double>& e);
58     void pack(const Matrix<SXElem>& e);
59     void pack(const Linsol& e);
60     void pack(const Function& e);
61     void pack(const GenericType& e);
62     void pack(const casadi_int& e);
63     void pack(const double& e);
64     void pack(const std::string& e);
65     void pack(const std::vector<Sparsity>& e);
66     void pack(const std::vector<MX>& e);
67     void pack(const std::vector< Matrix<double> >& e);
68     void pack(const std::vector< Matrix<SXElem> >& e);
69     void pack(const std::vector<Linsol>& e);
70     void pack(const std::vector<Function>& e);
71     void pack(const std::vector<GenericType>& e);
72     void pack(const std::vector<casadi_int>& e);
73     void pack(const std::vector<double>& e);
74     void pack(const std::vector<std::string>& e);
75 
76 
77 
78     enum SerializationType {
79       SERIALIZED_SPARSITY,
80       SERIALIZED_MX,
81       SERIALIZED_DM,
82       SERIALIZED_SX,
83       SERIALIZED_LINSOL,
84       SERIALIZED_FUNCTION,
85       SERIALIZED_GENERICTYPE,
86       SERIALIZED_INT,
87       SERIALIZED_DOUBLE,
88       SERIALIZED_STRING,
89       SERIALIZED_SPARSITY_VECTOR,
90       SERIALIZED_MX_VECTOR,
91       SERIALIZED_DM_VECTOR,
92       SERIALIZED_SX_VECTOR,
93       SERIALIZED_LINSOL_VECTOR,
94       SERIALIZED_FUNCTION_VECTOR,
95       SERIALIZED_GENERICTYPE_VECTOR,
96       SERIALIZED_INT_VECTOR,
97       SERIALIZED_DOUBLE_VECTOR,
98       SERIALIZED_STRING_VECTOR,
99     };
100 
101     static std::string type_to_string(SerializationType type);
102 
103     void connect(DeserializerBase & s);
104     void reset();
105 
106   protected:
107     SerializingStream& serializer();
108     std::unique_ptr<std::ostream> sstream_;
109     std::unique_ptr<SerializingStream> serializer_;
110   };
111 
112   class CASADI_EXPORT DeserializerBase {
113     friend class SerializerBase;
114   public:
115 #ifndef SWIG
116     DeserializerBase(std::unique_ptr<std::istream> stream);
117 #endif // SWIG
118     ~DeserializerBase();
119 
120     SerializerBase::SerializationType pop_type();
121 
122     Sparsity blind_unpack_sparsity();
123     MX blind_unpack_mx();
124     Matrix<double> blind_unpack_dm();
125     Matrix<SXElem> blind_unpack_sx();
126     Linsol blind_unpack_linsol();
127     Function blind_unpack_function();
128     GenericType blind_unpack_generictype();
129     casadi_int blind_unpack_int();
130     double blind_unpack_double();
131     std::string blind_unpack_string();
132     std::vector<Sparsity> blind_unpack_sparsity_vector();
133     std::vector<MX> blind_unpack_mx_vector();
134     std::vector< Matrix<double> > blind_unpack_dm_vector();
135     std::vector< Matrix<SXElem> > blind_unpack_sx_vector();
136     std::vector<Linsol> blind_unpack_linsol_vector();
137     std::vector<Function> blind_unpack_function_vector();
138     std::vector<GenericType> blind_unpack_generictype_vector();
139     std::vector<casadi_int> blind_unpack_int_vector();
140     std::vector<double> blind_unpack_double_vector();
141     std::vector<std::string> blind_unpack_string_vector();
142 
143     Sparsity unpack_sparsity();
144     MX unpack_mx();
145     Matrix<double> unpack_dm();
146     Matrix<SXElem> unpack_sx();
147     Linsol unpack_linsol();
148     Function unpack_function();
149     GenericType unpack_generictype();
150     casadi_int unpack_int();
151     double unpack_double();
152     std::string unpack_string();
153     std::vector<Sparsity> unpack_sparsity_vector();
154     std::vector<MX> unpack_mx_vector();
155     std::vector< Matrix<double> > unpack_dm_vector();
156     std::vector< Matrix<SXElem> > unpack_sx_vector();
157     std::vector<Linsol> unpack_linsol_vector();
158     std::vector<Function> unpack_function_vector();
159     std::vector<GenericType> unpack_generictype_vector();
160     std::vector<casadi_int> unpack_int_vector();
161     std::vector<double> unpack_double_vector();
162     std::vector<std::string> unpack_string_vector();
163 
164     void connect(SerializerBase & s);
165     void reset();
166 
167   protected:
168     DeserializingStream& deserializer();
169     std::unique_ptr<std::istream> dstream_;
170     std::unique_ptr<DeserializingStream> deserializer_;
171   };
172 
173   class CASADI_EXPORT StringSerializer : public SerializerBase {
174   public:
175     /** \brief Advanced serialization of CasADi objects
176      *
177      * This class is intended for advanced users that want to circumvent the restrictions
178      * of standard pickling/matlab save load, ie no raw SX/MX symbols allowed.
179      *
180      * \example
181      * x = SX.sym('x');
182      * s = StringSerializer();
183      * s.pack(x);
184      * s.pack(sin(x));
185      *
186      * data = s.encode();
187      *
188      * s = StringDeserializer(data);
189      * a = s.unpack();
190      * b = s.unpack();
191      * \endexample
192      *
193      * Note:
194      *  Saving SX/MX objects individually has a substantial overhead
195      *  (both time and length of encoded string).
196      *  You are encouraged to use the vector/list variants of 'save' for SX/MX to reduce
197      *  the overhead.
198      *
199      *
200      * \seealso Function::save, Function::serialize, StringDeserializer, FileSerializer
201      *
202      */
203     StringSerializer(const Dict& opts = Dict());
204     ~StringSerializer();
205 
206     /** \brief Returns a string that holds the serialized objects
207      *
208      * As a side effect, this method clears the internal buffer
209     */
210     std::string encode();
211   };
212 
213   class CASADI_EXPORT FileSerializer : public SerializerBase {
214   public:
215     /** \brief Advanced serialization of CasADi objects
216      *
217      * \seealso StringSerializer, FileDeserializer
218      */
219     FileSerializer(const std::string& fname, const Dict& opts = Dict());
220     ~FileSerializer();
221   };
222 
223   class CASADI_EXPORT StringDeserializer : public DeserializerBase {
224   public:
225 
226     /** \brief Advanced deserialization of CasADi objects
227      *
228      * \seealso StringDeserializer
229      */
230     StringDeserializer(const std::string& string);
231     ~StringDeserializer();
232 
233 
234     /** \brief Sets the string to deserialize objects from
235     */
236     void decode(const std::string& string);
237   };
238 
239   class CASADI_EXPORT FileDeserializer : public DeserializerBase {
240   public:
241      /** \brief Advanced deserialization of CasADi objects
242      *
243      * \seealso FileSerializer
244      */
245     FileDeserializer(const std::string& fname);
246     ~FileDeserializer();
247   };
248 
249 } // namespace casadi
250 
251 #endif // CASADI_SERIALIZER_HPP
252