source: rrlib_rtti_conversion/defined_conversions.cpp @ 0:d316daefc472

Last change on this file since 0:d316daefc472 was 0:d316daefc472, checked in by Max Reichardt <mreichardt@…>, 2 years ago

Initial commit

File size: 19.2 KB
Line 
1//
2// You received this file as part of RRLib
3// Robotics Research Library
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License along
18// with this program; if not, write to the Free Software Foundation, Inc.,
19// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21//----------------------------------------------------------------------
22/*!\file    rrlib/rtti_conversion/defined_conversions.cpp
23 *
24 * \author  Max Reichardt
25 *
26 * \date    2016-08-13
27 *
28 */
29//----------------------------------------------------------------------
30#include "rrlib/rtti_conversion/defined_conversions.h"
31
32//----------------------------------------------------------------------
33// External includes (system with <>, local with "")
34//----------------------------------------------------------------------
35#include <iomanip>
36
37//----------------------------------------------------------------------
38// Internal includes with ""
39//----------------------------------------------------------------------
40#include "rrlib/rtti_conversion/tStaticCastOperation.h"
41
42//----------------------------------------------------------------------
43// Debugging
44//----------------------------------------------------------------------
45#include <cassert>
46
47//----------------------------------------------------------------------
48// Namespace usage
49//----------------------------------------------------------------------
50
51//----------------------------------------------------------------------
52// Namespace declaration
53//----------------------------------------------------------------------
54namespace rrlib
55{
56namespace rtti
57{
58namespace conversion
59{
60
61//----------------------------------------------------------------------
62// Forward declarations / typedefs / enums
63//----------------------------------------------------------------------
64
65//----------------------------------------------------------------------
66// Const values
67//----------------------------------------------------------------------
68
69// Register static casts between builtin types
70auto& cBUILTIN_TYPE_CASTS = tStaticCastOperation::
71                            Register<int8_t, int16_t, true, true>()
72                            .Register<int8_t, int32_t, true, true>()
73                            .Register<int8_t, int64_t, true, true>()
74                            .Register<int8_t, uint8_t, true, true>()
75                            .Register<int8_t, uint16_t, true, true>()
76                            .Register<int8_t, uint32_t, true, true>()
77                            .Register<int8_t, uint64_t, true, true>()
78                            .Register<int8_t, float, true, true>()
79                            .Register<int8_t, double, true, true>()
80                            .Register<int8_t, bool, true, true>()
81
82                            .Register<int16_t, int32_t, true, true>()
83                            .Register<int16_t, int64_t, true, true>()
84                            .Register<int16_t, uint8_t, true, true>()
85                            .Register<int16_t, uint16_t, true, true>()
86                            .Register<int16_t, uint32_t, true, true>()
87                            .Register<int16_t, uint64_t, true, true>()
88                            .Register<int16_t, float, true, true>()
89                            .Register<int16_t, double, true, true>()
90                            .Register<int16_t, bool, true, true>()
91
92                            .Register<int32_t, int64_t, true, true>()
93                            .Register<int32_t, uint8_t, true, true>()
94                            .Register<int32_t, uint16_t, true, true>()
95                            .Register<int32_t, uint32_t, true, true>()
96                            .Register<int32_t, uint64_t, true, true>()
97                            .Register<int32_t, float, true, true>()
98                            .Register<int32_t, double, true, true>()
99                            .Register<int32_t, bool, true, true>()
100
101                            .Register<int64_t, uint8_t, true, true>()
102                            .Register<int64_t, uint16_t, true, true>()
103                            .Register<int64_t, uint32_t, true, true>()
104                            .Register<int64_t, uint64_t, true, true>()
105                            .Register<int64_t, float, true, true>()
106                            .Register<int64_t, double, true, true>()
107                            .Register<int64_t, bool, true, true>()
108
109                            .Register<uint8_t, uint16_t, true, true>()
110                            .Register<uint8_t, uint32_t, true, true>()
111                            .Register<uint8_t, uint64_t, true, true>()
112                            .Register<uint8_t, float, true, true>()
113                            .Register<uint8_t, double, true, true>()
114                            .Register<uint8_t, bool, true, true>()
115
116                            .Register<uint16_t, uint32_t, true, true>()
117                            .Register<uint16_t, uint64_t, true, true>()
118                            .Register<uint16_t, float, true, true>()
119                            .Register<uint16_t, double, true, true>()
120                            .Register<uint16_t, bool, true, true>()
121
122                            .Register<uint32_t, uint64_t, true, true>()
123                            .Register<uint32_t, float, true, true>()
124                            .Register<uint32_t, double, true, true>()
125                            .Register<uint32_t, bool, true, true>()
126
127                            .Register<uint64_t, float, true, true>()
128                            .Register<uint64_t, double, true, true>()
129                            .Register<uint64_t, bool, true, true>()
130
131                            .Register<float, double, true, true>()
132                            .Register<float, bool, true, true>()
133
134                            .Register<double, bool, true, true>();
135
136//----------------------------------------------------------------------
137// Implementation
138//----------------------------------------------------------------------
139
140class tToStringOperation : public tRegisteredConversionOperation
141{
142public:
143  tToStringOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("ToString", false), tSupportedTypeFilter::STRING_SERIALIZABLE, tDataType<std::string>(), nullptr, tParameterDefinition("Flags", tDataType<unsigned int>(), true))
144  {}
145
146  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type) const override
147  {
148    if ((source_type.GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE) && destination_type == tDataType<std::string>())
149    {
150      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
151    }
152    return tConversionOption();
153  }
154
155  static void MainConversionFunction(const tTypedConstPointer& source_object, std::string& destination, const tCurrentConversionOperation& operation)
156  {
157    rrlib::serialization::tStringOutputStream stream;
158
159    // init stream
160    /*auto precision = operation.GetParameterValue(0);
161    if (precision)
162    {
163      stream.GetWrappedStringStream() << std::setprecision(*precision.Get<int>());
164    }*/
165    auto flags = operation.GetParameterValue();
166    if (flags)
167    {
168      unsigned int f = *flags.Get<unsigned int>();
169      if (f)
170      {
171        if (f & eTSF_BOOL_ALPHA)
172        {
173          stream.GetWrappedStringStream() << std::boolalpha;
174        }
175        if (f & eTSF_SHOW_BASE)
176        {
177          stream.GetWrappedStringStream() << std::showbase;
178        }
179        if (f & eTSF_SHOW_POINT)
180        {
181          stream.GetWrappedStringStream() << std::showpoint;
182        }
183        if (f & eTSF_SHOW_POS)
184        {
185          stream.GetWrappedStringStream() << std::showpos;
186        }
187        if (f & eTSF_UPPER_CASE)
188        {
189          stream.GetWrappedStringStream() << std::uppercase;
190        }
191        if (f & eTSF_DEC)
192        {
193          stream.GetWrappedStringStream() << std::dec;
194        }
195        if (f & eTSF_HEX)
196        {
197          stream.GetWrappedStringStream() << std::hex;
198        }
199        if (f & eTSF_OCT)
200        {
201          stream.GetWrappedStringStream() << std::oct;
202        }
203        if (f & eTSF_FIXED)
204        {
205          stream.GetWrappedStringStream() << std::fixed;
206        }
207        if (f & eTSF_SCIENTIFIC)
208        {
209          stream.GetWrappedStringStream() << std::scientific;
210        }
211      }
212    }
213
214    source_object.Serialize(stream);
215    destination = stream.ToString();
216  }
217
218  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
219  {
220    std::string intermediate;
221    MainConversionFunction(source_object, intermediate, operation);
222    operation.Continue(tTypedConstPointer(&intermediate), destination_object);
223  }
224
225  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
226  {
227    MainConversionFunction(source_object, *destination_object.Get<std::string>(), operation);
228  }
229};
230
231class tStringDeserializationOperation : public tRegisteredConversionOperation
232{
233public:
234  tStringDeserializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("String Deserialization", false), tDataType<std::string>(), tSupportedTypeFilter::STRING_SERIALIZABLE)
235  {}
236
237  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type) const override
238  {
239    if ((destination_type.GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE) && source_type == tDataType<std::string>())
240    {
241      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
242    }
243    return tConversionOption();
244  }
245
246  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
247  {
248    tType inter_type = operation.compiled_operation.IntermediateType();
249    char intermediate_memory[inter_type.GetSize(true)];
250    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
251    serialization::tStringInputStream stream(*source_object.Get<std::string>());
252    intermediate_object->Deserialize(stream);
253    operation.Continue(*intermediate_object, destination_object);
254  }
255
256  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
257  {
258    serialization::tStringInputStream stream(*source_object.Get<std::string>());
259    destination_object.Deserialize(stream);
260  }
261};
262
263class tBinarySerializationOperation : public tRegisteredConversionOperation
264{
265public:
266  tBinarySerializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Binary Serialization", false), tSupportedTypeFilter::BINARY_SERIALIZABLE, tDataType<serialization::tMemoryBuffer>())
267  {}
268
269  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type) const override
270  {
271    if ((source_type.GetTypeTraits() & trait_flags::cIS_BINARY_SERIALIZABLE) && destination_type == tDataType<serialization::tMemoryBuffer>())
272    {
273      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
274    }
275    return tConversionOption();
276  }
277
278  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
279  {
280    serialization::tStackMemoryBuffer<serialization::cSTACK_BUFFERS_SIZE> buffer;
281    rrlib::serialization::tOutputStream stream(buffer);
282    source_object.Serialize(stream);
283    stream.Close();
284    operation.Continue(tTypedConstPointer(&static_cast<serialization::tMemoryBuffer&>(buffer)), destination_object);
285  }
286
287  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
288  {
289    serialization::tOutputStream stream(*destination_object.Get<serialization::tMemoryBuffer>());
290    destination_object.Serialize(stream);
291  }
292};
293
294class tBinaryDeserializationOperation : public tRegisteredConversionOperation
295{
296public:
297  tBinaryDeserializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Binary Deserialization", false), tDataType<serialization::tMemoryBuffer>(), tSupportedTypeFilter::STRING_SERIALIZABLE)
298  {}
299
300  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type) const override
301  {
302    if ((destination_type.GetTypeTraits() & trait_flags::cIS_BINARY_SERIALIZABLE) && source_type == tDataType<serialization::tMemoryBuffer>())
303    {
304      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
305    }
306    return tConversionOption();
307  }
308
309  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
310  {
311    tType inter_type = operation.compiled_operation.IntermediateType();
312    char intermediate_memory[inter_type.GetSize(true)];
313    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
314    serialization::tInputStream stream(*source_object.Get<serialization::tMemoryBuffer>());
315    intermediate_object->Deserialize(stream);
316    operation.Continue(*intermediate_object, destination_object);
317  }
318
319  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
320  {
321    serialization::tInputStream stream(*source_object.Get<serialization::tMemoryBuffer>());
322    destination_object.Deserialize(stream);
323  }
324};
325
326class tGetListElement : public tRegisteredConversionOperation
327{
328public:
329  tGetListElement() : tRegisteredConversionOperation(util::tManagedConstCharPointer("[]", false), tSupportedTypeFilter::GET_LIST_ELEMENT, tSupportedTypeFilter::GET_LIST_ELEMENT, nullptr, tParameterDefinition("Index", tDataType<unsigned int>(), true))
330  {}
331
332  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type) const override
333  {
334    if (source_type.IsListType() && source_type.GetElementType() == destination_type)
335    {
336      return tConversionOption(source_type, destination_type, &FirstConversionFunction, &GetDestinationReference);
337    }
338    return tConversionOption();
339  }
340
341  static tTypedConstPointer GetDestinationReference(const tTypedConstPointer& source_object, const tCurrentConversionOperation& operation)
342  {
343    auto index_parameter = operation.GetParameterValue();
344    unsigned int index = index_parameter ? (*index_parameter.Get<unsigned int>()) : 0;
345    auto result = source_object.GetVectorElement(index);
346    if (!result)
347    {
348      throw std::invalid_argument("Index out of bounds");
349    }
350    return result;
351  }
352
353  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
354  {
355    auto index_parameter = operation.GetParameterValue();
356    unsigned int index = index_parameter ? (*index_parameter.Get<unsigned int>()) : 0;
357    auto intermediate = source_object.GetVectorElement(index);
358    if (!intermediate)
359    {
360      throw std::invalid_argument("Index out of bounds");
361    }
362    operation.Continue(intermediate, destination_object);
363  }
364};
365
366class tForEach : public tRegisteredConversionOperation
367{
368public:
369  tForEach() : tRegisteredConversionOperation(util::tManagedConstCharPointer("For Each", false), tSupportedTypeFilter::GENERIC_VECTOR_CAST, tSupportedTypeFilter::GENERIC_VECTOR_CAST)
370  {}
371
372  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type) const override
373  {
374    if ((source_type.GetTypeTraits() & trait_flags::cIS_LIST_TYPE) && destination_type)
375    {
376      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
377    }
378    return tConversionOption();
379  }
380
381  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
382  {
383    size_t size = source_object.GetVectorSize();
384    destination_object.ResizeVector(size);
385    if (size)
386    {
387      tTypedConstPointer source_first = source_object.GetVectorElement(0);
388      tTypedPointer destination_first = destination_object.GetVectorElement(0);
389      operation.Continue(source_first, destination_object);
390      if (size > 1)
391      {
392        tTypedConstPointer source_next = source_object.GetVectorElement(1);
393        tTypedPointer destination_next = destination_object.GetVectorElement(1);
394        operation.Continue(source_next, destination_next);
395        size_t offset_source = static_cast<const char*>(source_next.GetRawDataPointer()) - static_cast<const char*>(source_first.GetRawDataPointer());
396        size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
397        for (size_t i = 2; i < size; i++)
398        {
399          source_next = tTypedConstPointer(static_cast<const char*>(source_next.GetRawDataPointer()) + offset_source, source_next.GetType());
400          destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_next.GetType());
401          operation.Continue(source_next, destination_next);
402        }
403      }
404    }
405  }
406
407  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
408  {
409    throw std::logic_error("Not supported as single or second operation");
410  }
411};
412
413
414const tToStringOperation cTO_STRING;
415const tRegisteredConversionOperation& cTO_STRING_OPERATION = cTO_STRING;
416const tStringDeserializationOperation cSTRING_DESERIALIZATION;
417const tRegisteredConversionOperation& cSTRING_DESERIALIZATION_OPERATION = cSTRING_DESERIALIZATION;
418const tBinarySerializationOperation cBINARY_SERIALIZATION;
419const tRegisteredConversionOperation& cBINARY_SERIALIZATION_OPERATION = cBINARY_SERIALIZATION;
420const tBinaryDeserializationOperation cBINARY_DESERIALIZATION;
421const tRegisteredConversionOperation& cBINARY_DESERIALIZATION_OPERATION = cBINARY_DESERIALIZATION;
422const tGetListElement cGET_LIST_ELEMENT;
423const tRegisteredConversionOperation& cGET_LIST_ELEMENT_OPERATION = cGET_LIST_ELEMENT;
424const tForEach cFOR_EACH;
425const tRegisteredConversionOperation& cFOR_EACH_OPERATION = cFOR_EACH;
426
427//----------------------------------------------------------------------
428// End of namespace declaration
429//----------------------------------------------------------------------
430}
431}
432}
Note: See TracBrowser for help on using the repository browser.