source: rrlib_rtti_conversion/defined_conversions.cpp @ 12:d8358d32e422

17.03
Last change on this file since 12:d8358d32e422 was 12:d8358d32e422, checked in by Max Reichardt <max.reichardt@…>, 5 months ago

Extends FOR_EACH conversion operation to support std::vector<bool> (with its non-standard memory layout)

File size: 34.7 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#include "rrlib/rtti_conversion/definition/tVoidFunctionConversionOperation.h"
42
43//----------------------------------------------------------------------
44// Debugging
45//----------------------------------------------------------------------
46#include <cassert>
47
48//----------------------------------------------------------------------
49// Namespace usage
50//----------------------------------------------------------------------
51
52//----------------------------------------------------------------------
53// Namespace declaration
54//----------------------------------------------------------------------
55namespace rrlib
56{
57namespace rtti
58{
59namespace conversion
60{
61
62//----------------------------------------------------------------------
63// Forward declarations / typedefs / enums
64//----------------------------------------------------------------------
65
66//----------------------------------------------------------------------
67// Const values
68//----------------------------------------------------------------------
69
70// Register static casts between builtin types
71auto& cBUILTIN_TYPE_CASTS = tStaticCastOperation::
72                            Register<int8_t, int16_t, true, true>()
73                            .Register<int8_t, int32_t, true, true>()
74                            .Register<int8_t, int64_t, true, true>()
75                            .Register<int8_t, uint8_t, true, true>()
76                            .Register<int8_t, uint16_t, true, true>()
77                            .Register<int8_t, uint32_t, true, true>()
78                            .Register<int8_t, uint64_t, true, true>()
79                            .Register<int8_t, float, true, true>()
80                            .Register<int8_t, double, true, true>()
81                            .Register<int8_t, bool, true, true>()
82
83                            .Register<int16_t, int32_t, true, true>()
84                            .Register<int16_t, int64_t, true, true>()
85                            .Register<int16_t, uint8_t, true, true>()
86                            .Register<int16_t, uint16_t, true, true>()
87                            .Register<int16_t, uint32_t, true, true>()
88                            .Register<int16_t, uint64_t, true, true>()
89                            .Register<int16_t, float, true, true>()
90                            .Register<int16_t, double, true, true>()
91                            .Register<int16_t, bool, true, true>()
92
93                            .Register<int32_t, int64_t, true, true>()
94                            .Register<int32_t, uint8_t, true, true>()
95                            .Register<int32_t, uint16_t, true, true>()
96                            .Register<int32_t, uint32_t, true, true>()
97                            .Register<int32_t, uint64_t, true, true>()
98                            .Register<int32_t, float, true, true>()
99                            .Register<int32_t, double, true, true>()
100                            .Register<int32_t, bool, true, true>()
101
102                            .Register<int64_t, uint8_t, true, true>()
103                            .Register<int64_t, uint16_t, true, true>()
104                            .Register<int64_t, uint32_t, true, true>()
105                            .Register<int64_t, uint64_t, true, true>()
106                            .Register<int64_t, float, true, true>()
107                            .Register<int64_t, double, true, true>()
108                            .Register<int64_t, bool, true, true>()
109
110                            .Register<uint8_t, uint16_t, true, true>()
111                            .Register<uint8_t, uint32_t, true, true>()
112                            .Register<uint8_t, uint64_t, true, true>()
113                            .Register<uint8_t, float, true, true>()
114                            .Register<uint8_t, double, true, true>()
115                            .Register<uint8_t, bool, true, true>()
116
117                            .Register<uint16_t, uint32_t, true, true>()
118                            .Register<uint16_t, uint64_t, true, true>()
119                            .Register<uint16_t, float, true, true>()
120                            .Register<uint16_t, double, true, true>()
121                            .Register<uint16_t, bool, true, true>()
122
123                            .Register<uint32_t, uint64_t, true, true>()
124                            .Register<uint32_t, float, true, true>()
125                            .Register<uint32_t, double, true, true>()
126                            .Register<uint32_t, bool, true, true>()
127
128                            .Register<uint64_t, float, true, true>()
129                            .Register<uint64_t, double, true, true>()
130                            .Register<uint64_t, bool, true, true>()
131
132                            .Register<float, double, true, true>()
133                            .Register<float, bool, true, true>()
134
135                            .Register<double, bool, true, true>()
136
137                            .Register<rrlib::serialization::tMemoryBuffer, std::vector<uint8_t>>();
138
139//----------------------------------------------------------------------
140// Implementation
141//----------------------------------------------------------------------
142
143namespace
144{
145
146const unsigned int cSTRING_OPERATION_DEFAULT_FLAGS = 0;
147const rrlib::rtti::tType cBOOL_VECTOR_TYPE = rrlib::rtti::tDataType<std::vector<bool>>();
148
149
150class tToStringOperation : public tRegisteredConversionOperation
151{
152public:
153  tToStringOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("ToString", false), tSupportedTypeFilter::STRING_SERIALIZABLE, tDataType<std::string>(), nullptr, tParameterDefinition("Flags", &cSTRING_OPERATION_DEFAULT_FLAGS, true))
154  {
155  }
156
157  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
158  {
159    if ((source_type.GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE) && destination_type == tDataType<std::string>())
160    {
161      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
162    }
163    return tConversionOption();
164  }
165
166  static void MainConversionFunction(const tTypedConstPointer& source_object, std::string& destination, const tCurrentConversionOperation& operation)
167  {
168    rrlib::serialization::tStringOutputStream stream;
169
170    // init stream
171    /*auto precision = operation.GetParameterValue(0);
172    if (precision)
173    {
174      stream.GetWrappedStringStream() << std::setprecision(*precision.Get<int>());
175    }*/
176    auto flags = operation.GetParameterValue();
177    if (flags)
178    {
179      unsigned int f = *flags.Get<unsigned int>();
180      if (f)
181      {
182        if (f & eTSF_BOOL_ALPHA)
183        {
184          stream.GetWrappedStringStream() << std::boolalpha;
185        }
186        if (f & eTSF_SHOW_BASE)
187        {
188          stream.GetWrappedStringStream() << std::showbase;
189        }
190        if (f & eTSF_SHOW_POINT)
191        {
192          stream.GetWrappedStringStream() << std::showpoint;
193        }
194        if (f & eTSF_SHOW_POS)
195        {
196          stream.GetWrappedStringStream() << std::showpos;
197        }
198        if (f & eTSF_UPPER_CASE)
199        {
200          stream.GetWrappedStringStream() << std::uppercase;
201        }
202        if (f & eTSF_DEC)
203        {
204          stream.GetWrappedStringStream() << std::dec;
205        }
206        if (f & eTSF_HEX)
207        {
208          stream.GetWrappedStringStream() << std::hex;
209        }
210        if (f & eTSF_OCT)
211        {
212          stream.GetWrappedStringStream() << std::oct;
213        }
214        if (f & eTSF_FIXED)
215        {
216          stream.GetWrappedStringStream() << std::fixed;
217        }
218        if (f & eTSF_SCIENTIFIC)
219        {
220          stream.GetWrappedStringStream() << std::scientific;
221        }
222      }
223    }
224
225    source_object.Serialize(stream);
226    destination = stream.ToString();
227  }
228
229  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
230  {
231    std::string intermediate;
232    MainConversionFunction(source_object, intermediate, operation);
233    operation.Continue(tTypedConstPointer(&intermediate), destination_object);
234  }
235
236  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
237  {
238    MainConversionFunction(source_object, *destination_object.Get<std::string>(), operation);
239  }
240} cTO_STRING;
241
242class tStringDeserializationOperation : public tRegisteredConversionOperation
243{
244public:
245  tStringDeserializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("String Deserialization", false), tDataType<std::string>(), tSupportedTypeFilter::STRING_SERIALIZABLE, nullptr, tParameterDefinition(), &cTO_STRING)
246  {}
247
248  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
249  {
250    if ((destination_type.GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE) && source_type == tDataType<std::string>())
251    {
252      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
253    }
254    return tConversionOption();
255  }
256
257  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
258  {
259    tType inter_type = operation.compiled_operation.IntermediateType();
260    char intermediate_memory[inter_type.GetSize(true)];
261    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
262    serialization::tStringInputStream stream(*source_object.Get<std::string>());
263    intermediate_object->Deserialize(stream);
264    operation.Continue(*intermediate_object, destination_object);
265  }
266
267  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
268  {
269    serialization::tStringInputStream stream(*source_object.Get<std::string>());
270    destination_object.Deserialize(stream);
271  }
272} cSTRING_DESERIALIZATION;
273
274class tBinarySerializationOperation : public tRegisteredConversionOperation
275{
276public:
277  tBinarySerializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Binary Serialization", false), tSupportedTypeFilter::BINARY_SERIALIZABLE, tDataType<serialization::tMemoryBuffer>())
278  {}
279
280  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
281  {
282    if ((source_type.GetTypeTraits() & trait_flags::cIS_BINARY_SERIALIZABLE) && destination_type == tDataType<serialization::tMemoryBuffer>())
283    {
284      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
285    }
286    return tConversionOption();
287  }
288
289  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
290  {
291    serialization::tStackMemoryBuffer<serialization::cSTACK_BUFFERS_SIZE> buffer;
292    rrlib::serialization::tOutputStream stream(buffer);
293    source_object.Serialize(stream);
294    stream.Close();
295    operation.Continue(tTypedConstPointer(&static_cast<serialization::tMemoryBuffer&>(buffer)), destination_object);
296  }
297
298  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
299  {
300    serialization::tOutputStream stream(*destination_object.Get<serialization::tMemoryBuffer>());
301    destination_object.Serialize(stream);
302  }
303} cBINARY_SERIALIZATION;
304
305class tBinaryDeserializationOperation : public tRegisteredConversionOperation
306{
307public:
308  tBinaryDeserializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Binary Deserialization", false), tDataType<serialization::tMemoryBuffer>(), tSupportedTypeFilter::BINARY_SERIALIZABLE, nullptr, tParameterDefinition(), &cBINARY_SERIALIZATION)
309  {}
310
311  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
312  {
313    if ((destination_type.GetTypeTraits() & trait_flags::cIS_BINARY_SERIALIZABLE) && source_type == tDataType<serialization::tMemoryBuffer>())
314    {
315      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
316    }
317    return tConversionOption();
318  }
319
320  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
321  {
322    tType inter_type = operation.compiled_operation.IntermediateType();
323    char intermediate_memory[inter_type.GetSize(true)];
324    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
325    serialization::tInputStream stream(*source_object.Get<serialization::tMemoryBuffer>());
326    intermediate_object->Deserialize(stream);
327    operation.Continue(*intermediate_object, destination_object);
328  }
329
330  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
331  {
332    serialization::tInputStream stream(*source_object.Get<serialization::tMemoryBuffer>());
333    destination_object.Deserialize(stream);
334  }
335} cBINARY_DESERIALIZATION;
336
337class tGetListElement : public tRegisteredConversionOperation
338{
339public:
340  tGetListElement() : tRegisteredConversionOperation(util::tManagedConstCharPointer("[]", false), tSupportedTypeFilter::GET_LIST_ELEMENT, tSupportedTypeFilter::GET_LIST_ELEMENT, nullptr, tParameterDefinition("Index", tDataType<unsigned int>(), true))
341  {}
342
343  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
344  {
345    if (source_type.IsListType() && source_type.GetElementType() == destination_type)
346    {
347      return tConversionOption(source_type, destination_type, &FirstConversionFunction, &GetDestinationReference);
348    }
349    unsigned int index = 0;
350    if (parameter && parameter->GetType() == tDataType<std::string>())
351    {
352      index = serialization::Deserialize<unsigned int>(parameter->GetData<std::string>());
353    }
354    else if (parameter)
355    {
356      assert(parameter->GetType() == tDataType<unsigned int>());
357      index = parameter->GetData<unsigned int>();
358    }
359    {
360      rtti::tType current_type = source_type;
361      while ((current_type.GetTypeTraits() & rtti::trait_flags::cINHERITS_UNDERLYING_TYPE_ELEMENT_ACCESS_OPERATIONS) && (!current_type.IsArray()) && current_type.GetUnderlyingType() != current_type)
362      {
363        current_type = current_type.GetUnderlyingType();
364      }
365      if (current_type.IsArray() && current_type.GetElementType() == destination_type && index < current_type.GetArraySize())
366      {
367        return tConversionOption(source_type, destination_type, index * current_type.GetElementType().GetSize());
368      }
369    }
370    return tConversionOption();
371  }
372
373  static tTypedConstPointer GetDestinationReference(const tTypedConstPointer& source_object, const tCurrentConversionOperation& operation)
374  {
375    auto index_parameter = operation.GetParameterValue();
376    unsigned int index = index_parameter ? (*index_parameter.Get<unsigned int>()) : 0;
377    auto result = source_object.GetVectorElement(index);
378    if (!result)
379    {
380      throw std::invalid_argument("Index out of bounds");
381    }
382    return result;
383  }
384
385  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
386  {
387    auto index_parameter = operation.GetParameterValue();
388    unsigned int index = index_parameter ? (*index_parameter.Get<unsigned int>()) : 0;
389    auto intermediate = source_object.GetVectorElement(index);
390    if (!intermediate)
391    {
392      throw std::invalid_argument("Index out of bounds");
393    }
394    operation.Continue(intermediate, destination_object);
395  }
396} cGET_LIST_ELEMENT;
397
398class tForEach : public tRegisteredConversionOperation
399{
400public:
401  tForEach() : tRegisteredConversionOperation(util::tManagedConstCharPointer("For Each", false), tSupportedTypeFilter::FOR_EACH, tSupportedTypeFilter::FOR_EACH)
402  {}
403
404  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
405  {
406    if ((source_type.IsListType() || source_type.IsArray()) && destination_type)
407    {
408      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
409    }
410    return tConversionOption();
411  }
412
413  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
414  {
415    const tType& source_type = source_object.GetType();
416    const tType& destination_type = destination_object.GetType();
417    const tType source_element_type = source_type.GetElementType();
418    const tType destination_element_type = destination_type.GetElementType();
419    size_t size = source_type.IsArray() ? source_type.GetArraySize() : source_object.GetVectorSize();
420    if (source_type.IsListType() && destination_type.IsListType())
421    {
422      destination_object.ResizeVector(size);
423      if (size)
424      {
425        if (source_type == cBOOL_VECTOR_TYPE)
426        {
427          bool wrapped_bool = false;
428          tTypedPointer temp_source_pointer(&wrapped_bool);
429          const std::vector<bool>& source = *source_object.Get<std::vector<bool>>();
430
431          wrapped_bool = source[0];
432          tTypedPointer destination_first = destination_object.GetVectorElement(0);
433          operation.Continue(temp_source_pointer, destination_first);
434          if (size > 1)
435          {
436            wrapped_bool = source[1];
437            tTypedPointer destination_next = destination_object.GetVectorElement(1);
438            operation.Continue(temp_source_pointer, destination_next);
439            size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
440            for (size_t i = 2; i < size; i++)
441            {
442              wrapped_bool = source[i];
443              destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_element_type);
444              operation.Continue(temp_source_pointer, destination_next);
445            }
446          }
447        }
448        else if (destination_type == cBOOL_VECTOR_TYPE)
449        {
450          bool wrapped_bool = false;
451          tTypedPointer temp_destination_pointer(&wrapped_bool);
452          std::vector<bool>& destination = *destination_object.Get<std::vector<bool>>();
453
454          tTypedConstPointer source_first = source_object.GetVectorElement(0);
455          operation.Continue(source_first, temp_destination_pointer);
456          destination[0] = wrapped_bool;
457          if (size > 1)
458          {
459            tTypedConstPointer source_next = source_object.GetVectorElement(1);
460            operation.Continue(source_next, temp_destination_pointer);
461            size_t offset_source = static_cast<const char*>(source_next.GetRawDataPointer()) - static_cast<const char*>(source_first.GetRawDataPointer());
462            destination[1] = wrapped_bool;
463            for (size_t i = 2; i < size; i++)
464            {
465              source_next = tTypedConstPointer(static_cast<const char*>(source_next.GetRawDataPointer()) + offset_source, source_element_type);
466              operation.Continue(source_next, temp_destination_pointer);
467              destination[i] = wrapped_bool;
468            }
469          }
470        }
471        else
472        {
473          tTypedConstPointer source_first = source_object.GetVectorElement(0);
474          tTypedPointer destination_first = destination_object.GetVectorElement(0);
475          operation.Continue(source_first, destination_first);
476          if (size > 1)
477          {
478            tTypedConstPointer source_next = source_object.GetVectorElement(1);
479            tTypedPointer destination_next = destination_object.GetVectorElement(1);
480            operation.Continue(source_next, destination_next);
481            size_t offset_source = static_cast<const char*>(source_next.GetRawDataPointer()) - static_cast<const char*>(source_first.GetRawDataPointer());
482            size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
483            for (size_t i = 2; i < size; i++)
484            {
485              source_next = tTypedConstPointer(static_cast<const char*>(source_next.GetRawDataPointer()) + offset_source, source_element_type);
486              destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_element_type);
487              operation.Continue(source_next, destination_next);
488            }
489          }
490        }
491      }
492    }
493    else if (source_type.IsArray() && destination_type.IsArray())
494    {
495      if (size != destination_type.GetArraySize())
496      {
497        throw std::runtime_error("Arrays must have the same size");
498      }
499
500      size_t source_element_offset = source_type.GetSize() / size;
501      size_t destination_element_offset = destination_type.GetSize() / size;
502      for (size_t i = 0; i < size; i++)
503      {
504        tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type);
505        tTypedPointer destination(static_cast<char*>(destination_object.GetRawDataPointer()) + i * destination_element_offset, destination_element_type);
506        operation.Continue(source, destination);
507      }
508    }
509    else if (source_type.IsArray() && destination_type.IsListType())
510    {
511      size_t size = source_type.GetArraySize();
512      destination_object.ResizeVector(size);
513      if (size)
514      {
515        size_t source_element_offset = source_type.GetSize() / size;
516        tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()), source_element_type);
517
518        if (destination_type == cBOOL_VECTOR_TYPE)
519        {
520          bool wrapped_bool = false;
521          tTypedPointer temp_destination_pointer(&wrapped_bool);
522          std::vector<bool>& destination = *destination_object.Get<std::vector<bool>>();
523
524          operation.Continue(source, temp_destination_pointer);
525          destination[0] = wrapped_bool;
526          if (size > 1)
527          {
528            tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_element_type);
529            operation.Continue(source, temp_destination_pointer);
530            destination[1] = wrapped_bool;
531            for (size_t i = 2; i < size; i++)
532            {
533              tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type);
534              operation.Continue(source, temp_destination_pointer);
535              destination[i] = wrapped_bool;
536            }
537          }
538        }
539        else
540        {
541          tTypedPointer destination_first = destination_object.GetVectorElement(0);
542          operation.Continue(source, destination_first);
543          if (size > 1)
544          {
545            tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_element_type);
546            tTypedPointer destination_next = destination_object.GetVectorElement(1);
547            operation.Continue(source, destination_next);
548            size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
549            for (size_t i = 2; i < size; i++)
550            {
551              tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type);
552              destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_element_type);
553              operation.Continue(source, destination_next);
554            }
555          }
556        }
557      }
558    }
559    else
560    {
561      throw std::runtime_error("Unsupported types for 'For Each' Operation");
562    }
563  }
564
565  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
566  {
567    throw std::logic_error("Not supported as single or second operation");
568  }
569} cFOR_EACH;
570
571class tArrayToVector : public tRegisteredConversionOperation
572{
573public:
574  tArrayToVector() : tRegisteredConversionOperation(util::tManagedConstCharPointer("ToVector", false), tSupportedTypeFilter::ARRAY_TO_VECTOR, tSupportedTypeFilter::ARRAY_TO_VECTOR)
575  {}
576
577  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
578  {
579    if (source_type.IsArray() && destination_type.IsListType() && source_type.GetElementType() == destination_type.GetElementType())
580    {
581      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
582    }
583    return tConversionOption();
584  }
585
586  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
587  {
588    tType inter_type = operation.compiled_operation.IntermediateType();
589    char intermediate_memory[inter_type.GetSize(true)];
590    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
591    FinalConversionFunction(source_object, *intermediate_object, operation);
592    operation.Continue(*intermediate_object, destination_object);
593  }
594
595  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
596  {
597    const tType& source_type = source_object.GetType();
598    const tType source_element_type = source_type.GetElementType();
599    size_t size = source_type.GetArraySize();
600    destination_object.ResizeVector(size);
601    if (size)
602    {
603      size_t source_element_offset = source_type.GetSize() / size;
604      tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()), source_element_type);
605      tTypedPointer destination_first = destination_object.GetVectorElement(0);
606      destination_first.DeepCopyFrom(source);
607      if (size > 1)
608      {
609        tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_element_type);
610        tTypedPointer destination_next = destination_object.GetVectorElement(1);
611        destination_next.DeepCopyFrom(source);
612        size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
613        for (size_t i = 2; i < size; i++)
614        {
615          tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type);
616          destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_next.GetType());
617          destination_next.DeepCopyFrom(source);
618        }
619      }
620    }
621  }
622} cARRAY_TO_VECTOR;
623
624class tGetTupleElement : public tRegisteredConversionOperation
625{
626public:
627  tGetTupleElement() : tRegisteredConversionOperation(util::tManagedConstCharPointer("get", false), tSupportedTypeFilter::GET_TUPLE_ELEMENT, tSupportedTypeFilter::GET_TUPLE_ELEMENT, nullptr, tParameterDefinition("Index", tDataType<unsigned int>(), true))
628  {}
629
630  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
631  {
632    unsigned int index = 0;
633    if (parameter && parameter->GetType() == tDataType<std::string>())
634    {
635      index = serialization::Deserialize<unsigned int>(parameter->GetData<std::string>());
636    }
637    else if (parameter)
638    {
639      assert(parameter->GetType() == tDataType<unsigned int>());
640      index = parameter->GetData<unsigned int>();
641    }
642    auto tuple_types = source_type.GetTupleTypes();
643    if (index < tuple_types.second && destination_type == tType(tuple_types.first[index].type_info))
644    {
645      return tConversionOption(source_type, destination_type, tuple_types.first[index].offset);
646    }
647    return tConversionOption();
648  }
649} cGET_TUPLE_ELEMENT;
650
651class tWrapByteVectorOperation : public tRegisteredConversionOperation
652{
653public:
654  tWrapByteVectorOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Wrap", false), tDataType<std::vector<uint8_t>>(), tDataType<rrlib::serialization::tMemoryBuffer>(), &cCONVERSION_OPTION)
655  {}
656
657  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
658  {
659    const std::vector<uint8_t>& vector = *source_object.Get<std::vector<uint8_t>>();
660    if (vector.size())
661    {
662      const rrlib::serialization::tMemoryBuffer buffer(const_cast<uint8_t*>(&vector[0]), vector.size());
663      operation.Continue(tTypedConstPointer(&buffer), destination_object);
664    }
665    else
666    {
667      const rrlib::serialization::tMemoryBuffer buffer(0);
668      operation.Continue(tTypedConstPointer(&buffer), destination_object);
669    }
670  }
671
672  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
673  {
674    rrlib::serialization::tMemoryBuffer& buffer = *destination_object.Get<rrlib::serialization::tMemoryBuffer>();
675    const std::vector<uint8_t>& vector = *source_object.Get<std::vector<uint8_t>>();
676    buffer = rrlib::serialization::tMemoryBuffer(const_cast<uint8_t*>(&vector[0]), vector.size());
677    //const rrlib::serialization::tMemoryBuffer temp_buffer(const_cast<uint8_t*>(&vector[0]), vector.size());
678    //buffer.CopyFrom(temp_buffer);
679  }
680
681  static constexpr tConversionOption cCONVERSION_OPTION = tConversionOption(tDataType<std::vector<uint8_t>>(), tDataType<rrlib::serialization::tMemoryBuffer>(), true, &FirstConversionFunction, &FinalConversionFunction);
682} cWRAP_BYTE_VECTOR;
683
684constexpr tConversionOption tWrapByteVectorOperation::cCONVERSION_OPTION;
685
686class tListSize : public tRegisteredConversionOperation
687{
688public:
689  tListSize() : tRegisteredConversionOperation(util::tManagedConstCharPointer("size()", false), tSupportedTypeFilter::LISTS, tDataType<size_t>())
690  {}
691
692  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
693  {
694    if (source_type.IsListType() && destination_type == tDataType<size_t>())
695    {
696      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
697    }
698    return tConversionOption();
699  }
700
701  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
702  {
703    size_t size = source_object.GetVectorSize();
704    operation.Continue(tTypedConstPointer(&size), destination_object);
705  }
706
707  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
708  {
709    (*destination_object.Get<size_t>()) = source_object.GetVectorSize();
710  }
711} cLIST_SIZE;
712
713void StringToVectorConversionFunction(const std::string& source, std::vector<char>& destination)
714{
715  destination = std::vector<char>(source.begin(), source.end());
716}
717
718void VectorToStringConversionFunction(const std::vector<char>& source, std::string& destination)
719{
720  destination = std::string(source.begin(), source.end());
721}
722
723const tVoidFunctionConversionOperation<std::string, std::vector<char>, decltype(&StringToVectorConversionFunction), &StringToVectorConversionFunction> cSTRING_TO_VECTOR("ToVector");
724const tVoidFunctionConversionOperation<std::vector<char>, std::string, decltype(&VectorToStringConversionFunction), &VectorToStringConversionFunction> cVECTOR_TO_STRING("MakeString");
725
726}
727
728const tRegisteredConversionOperation& cTO_STRING_OPERATION = cTO_STRING;
729const tRegisteredConversionOperation& cSTRING_DESERIALIZATION_OPERATION = cSTRING_DESERIALIZATION;
730const tRegisteredConversionOperation& cBINARY_SERIALIZATION_OPERATION = cBINARY_SERIALIZATION;
731const tRegisteredConversionOperation& cBINARY_DESERIALIZATION_OPERATION = cBINARY_DESERIALIZATION;
732
733const tRegisteredConversionOperation& cGET_LIST_ELEMENT_OPERATION = cGET_LIST_ELEMENT;
734const tRegisteredConversionOperation& cFOR_EACH_OPERATION = cFOR_EACH;
735const tRegisteredConversionOperation& cARRAY_TO_VECTOR_OPERATION = cARRAY_TO_VECTOR;
736const tRegisteredConversionOperation& cGET_TUPLE_ELEMENT_OPERATION = cGET_TUPLE_ELEMENT;
737
738const tRegisteredConversionOperation& cWRAP_BYTE_VECTOR_OPERATION = cWRAP_BYTE_VECTOR;
739const tRegisteredConversionOperation& cLIST_SIZE_OPERATION = cLIST_SIZE;
740const tRegisteredConversionOperation& cSTRING_TO_VECTOR_OPERATION = cSTRING_TO_VECTOR;
741const tRegisteredConversionOperation& cMAKE_STRING_OPERATION = cVECTOR_TO_STRING;
742
743
744
745//----------------------------------------------------------------------
746// End of namespace declaration
747//----------------------------------------------------------------------
748}
749}
750}
Note: See TracBrowser for help on using the repository browser.