source: rrlib_rtti_conversion/defined_conversions.cpp @ 9:f909044a9f7b

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

Adds option to specify type conversions operations that are not usually combined (you could call combinations deprecated) and fixes various bugs found with unit test in finroc_plugins_runtime_construction

File size: 30.9 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;
147
148class tToStringOperation : public tRegisteredConversionOperation
149{
150public:
151  tToStringOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("ToString", false), tSupportedTypeFilter::STRING_SERIALIZABLE, tDataType<std::string>(), nullptr, tParameterDefinition("Flags", &cSTRING_OPERATION_DEFAULT_FLAGS, true))
152  {
153  }
154
155  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
156  {
157    if ((source_type.GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE) && destination_type == tDataType<std::string>())
158    {
159      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
160    }
161    return tConversionOption();
162  }
163
164  static void MainConversionFunction(const tTypedConstPointer& source_object, std::string& destination, const tCurrentConversionOperation& operation)
165  {
166    rrlib::serialization::tStringOutputStream stream;
167
168    // init stream
169    /*auto precision = operation.GetParameterValue(0);
170    if (precision)
171    {
172      stream.GetWrappedStringStream() << std::setprecision(*precision.Get<int>());
173    }*/
174    auto flags = operation.GetParameterValue();
175    if (flags)
176    {
177      unsigned int f = *flags.Get<unsigned int>();
178      if (f)
179      {
180        if (f & eTSF_BOOL_ALPHA)
181        {
182          stream.GetWrappedStringStream() << std::boolalpha;
183        }
184        if (f & eTSF_SHOW_BASE)
185        {
186          stream.GetWrappedStringStream() << std::showbase;
187        }
188        if (f & eTSF_SHOW_POINT)
189        {
190          stream.GetWrappedStringStream() << std::showpoint;
191        }
192        if (f & eTSF_SHOW_POS)
193        {
194          stream.GetWrappedStringStream() << std::showpos;
195        }
196        if (f & eTSF_UPPER_CASE)
197        {
198          stream.GetWrappedStringStream() << std::uppercase;
199        }
200        if (f & eTSF_DEC)
201        {
202          stream.GetWrappedStringStream() << std::dec;
203        }
204        if (f & eTSF_HEX)
205        {
206          stream.GetWrappedStringStream() << std::hex;
207        }
208        if (f & eTSF_OCT)
209        {
210          stream.GetWrappedStringStream() << std::oct;
211        }
212        if (f & eTSF_FIXED)
213        {
214          stream.GetWrappedStringStream() << std::fixed;
215        }
216        if (f & eTSF_SCIENTIFIC)
217        {
218          stream.GetWrappedStringStream() << std::scientific;
219        }
220      }
221    }
222
223    source_object.Serialize(stream);
224    destination = stream.ToString();
225  }
226
227  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
228  {
229    std::string intermediate;
230    MainConversionFunction(source_object, intermediate, operation);
231    operation.Continue(tTypedConstPointer(&intermediate), destination_object);
232  }
233
234  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
235  {
236    MainConversionFunction(source_object, *destination_object.Get<std::string>(), operation);
237  }
238} cTO_STRING;
239
240class tStringDeserializationOperation : public tRegisteredConversionOperation
241{
242public:
243  tStringDeserializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("String Deserialization", false), tDataType<std::string>(), tSupportedTypeFilter::STRING_SERIALIZABLE, nullptr, tParameterDefinition(), &cTO_STRING)
244  {}
245
246  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
247  {
248    if ((destination_type.GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE) && source_type == tDataType<std::string>())
249    {
250      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
251    }
252    return tConversionOption();
253  }
254
255  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
256  {
257    tType inter_type = operation.compiled_operation.IntermediateType();
258    char intermediate_memory[inter_type.GetSize(true)];
259    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
260    serialization::tStringInputStream stream(*source_object.Get<std::string>());
261    intermediate_object->Deserialize(stream);
262    operation.Continue(*intermediate_object, destination_object);
263  }
264
265  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
266  {
267    serialization::tStringInputStream stream(*source_object.Get<std::string>());
268    destination_object.Deserialize(stream);
269  }
270} cSTRING_DESERIALIZATION;
271
272class tBinarySerializationOperation : public tRegisteredConversionOperation
273{
274public:
275  tBinarySerializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Binary Serialization", false), tSupportedTypeFilter::BINARY_SERIALIZABLE, tDataType<serialization::tMemoryBuffer>())
276  {}
277
278  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
279  {
280    if ((source_type.GetTypeTraits() & trait_flags::cIS_BINARY_SERIALIZABLE) && destination_type == tDataType<serialization::tMemoryBuffer>())
281    {
282      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
283    }
284    return tConversionOption();
285  }
286
287  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
288  {
289    serialization::tStackMemoryBuffer<serialization::cSTACK_BUFFERS_SIZE> buffer;
290    rrlib::serialization::tOutputStream stream(buffer);
291    source_object.Serialize(stream);
292    stream.Close();
293    operation.Continue(tTypedConstPointer(&static_cast<serialization::tMemoryBuffer&>(buffer)), destination_object);
294  }
295
296  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
297  {
298    serialization::tOutputStream stream(*destination_object.Get<serialization::tMemoryBuffer>());
299    destination_object.Serialize(stream);
300  }
301} cBINARY_SERIALIZATION;
302
303class tBinaryDeserializationOperation : public tRegisteredConversionOperation
304{
305public:
306  tBinaryDeserializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Binary Deserialization", false), tDataType<serialization::tMemoryBuffer>(), tSupportedTypeFilter::BINARY_SERIALIZABLE, nullptr, tParameterDefinition(), &cBINARY_SERIALIZATION)
307  {}
308
309  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
310  {
311    if ((destination_type.GetTypeTraits() & trait_flags::cIS_BINARY_SERIALIZABLE) && source_type == tDataType<serialization::tMemoryBuffer>())
312    {
313      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
314    }
315    return tConversionOption();
316  }
317
318  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
319  {
320    tType inter_type = operation.compiled_operation.IntermediateType();
321    char intermediate_memory[inter_type.GetSize(true)];
322    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
323    serialization::tInputStream stream(*source_object.Get<serialization::tMemoryBuffer>());
324    intermediate_object->Deserialize(stream);
325    operation.Continue(*intermediate_object, destination_object);
326  }
327
328  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
329  {
330    serialization::tInputStream stream(*source_object.Get<serialization::tMemoryBuffer>());
331    destination_object.Deserialize(stream);
332  }
333} cBINARY_DESERIALIZATION;
334
335class tGetListElement : public tRegisteredConversionOperation
336{
337public:
338  tGetListElement() : tRegisteredConversionOperation(util::tManagedConstCharPointer("[]", false), tSupportedTypeFilter::GET_LIST_ELEMENT, tSupportedTypeFilter::GET_LIST_ELEMENT, nullptr, tParameterDefinition("Index", tDataType<unsigned int>(), true))
339  {}
340
341  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
342  {
343    if (source_type.IsListType() && source_type.GetElementType() == destination_type)
344    {
345      return tConversionOption(source_type, destination_type, &FirstConversionFunction, &GetDestinationReference);
346    }
347    unsigned int index = 0;
348    if (parameter && parameter->GetType() == tDataType<std::string>())
349    {
350      index = serialization::Deserialize<unsigned int>(parameter->GetData<std::string>());
351    }
352    else if (parameter)
353    {
354      assert(parameter->GetType() == tDataType<unsigned int>());
355      index = parameter->GetData<unsigned int>();
356    }
357    if (source_type.IsArray() && source_type.GetElementType() == destination_type && index < source_type.GetArraySize())
358    {
359      return tConversionOption(source_type, destination_type, index * source_type.GetElementType().GetSize());
360    }
361    return tConversionOption();
362  }
363
364  static tTypedConstPointer GetDestinationReference(const tTypedConstPointer& source_object, const tCurrentConversionOperation& operation)
365  {
366    auto index_parameter = operation.GetParameterValue();
367    unsigned int index = index_parameter ? (*index_parameter.Get<unsigned int>()) : 0;
368    auto result = source_object.GetVectorElement(index);
369    if (!result)
370    {
371      throw std::invalid_argument("Index out of bounds");
372    }
373    return result;
374  }
375
376  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
377  {
378    auto index_parameter = operation.GetParameterValue();
379    unsigned int index = index_parameter ? (*index_parameter.Get<unsigned int>()) : 0;
380    auto intermediate = source_object.GetVectorElement(index);
381    if (!intermediate)
382    {
383      throw std::invalid_argument("Index out of bounds");
384    }
385    operation.Continue(intermediate, destination_object);
386  }
387} cGET_LIST_ELEMENT;
388
389class tForEach : public tRegisteredConversionOperation
390{
391public:
392  tForEach() : tRegisteredConversionOperation(util::tManagedConstCharPointer("For Each", false), tSupportedTypeFilter::FOR_EACH, tSupportedTypeFilter::FOR_EACH)
393  {}
394
395  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
396  {
397    if ((source_type.IsListType() || source_type.IsArray()) && destination_type)
398    {
399      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
400    }
401    return tConversionOption();
402  }
403
404  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
405  {
406    const tType& source_type = source_object.GetType();
407    const tType& destination_type = destination_object.GetType();
408    const tType source_element_type = source_type.GetElementType();
409    const tType destination_element_type = destination_type.GetElementType();
410    size_t size = source_type.IsArray() ? source_type.GetArraySize() : source_object.GetVectorSize();
411    if (source_type.IsListType() && destination_type.IsListType())
412    {
413      destination_object.ResizeVector(size);
414      if (size)
415      {
416        tTypedConstPointer source_first = source_object.GetVectorElement(0);
417        tTypedPointer destination_first = destination_object.GetVectorElement(0);
418        operation.Continue(source_first, destination_first);
419        if (size > 1)
420        {
421          tTypedConstPointer source_next = source_object.GetVectorElement(1);
422          tTypedPointer destination_next = destination_object.GetVectorElement(1);
423          operation.Continue(source_next, destination_next);
424          size_t offset_source = static_cast<const char*>(source_next.GetRawDataPointer()) - static_cast<const char*>(source_first.GetRawDataPointer());
425          size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
426          for (size_t i = 2; i < size; i++)
427          {
428            source_next = tTypedConstPointer(static_cast<const char*>(source_next.GetRawDataPointer()) + offset_source, source_element_type);
429            destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_element_type);
430            operation.Continue(source_next, destination_next);
431          }
432        }
433      }
434    }
435    else if (source_type.IsArray() && destination_type.IsArray())
436    {
437      if (size != destination_type.GetArraySize())
438      {
439        throw std::runtime_error("Arrays must have the same size");
440      }
441
442      size_t source_element_offset = source_type.GetSize() / size;
443      size_t destination_element_offset = destination_type.GetSize() / size;
444      for (size_t i = 0; i < size; i++)
445      {
446        tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type);
447        tTypedPointer destination(static_cast<char*>(destination_object.GetRawDataPointer()) + i * destination_element_offset, destination_element_type);
448        operation.Continue(source, destination);
449      }
450    }
451    else if (source_type.IsArray() && destination_type.IsListType())
452    {
453      size_t size = source_type.GetArraySize();
454      destination_object.ResizeVector(size);
455      if (size)
456      {
457        size_t source_element_offset = source_type.GetSize() / size;
458        tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()), source_element_type);
459        tTypedPointer destination_first = destination_object.GetVectorElement(0);
460        operation.Continue(source, destination_first);
461        if (size > 1)
462        {
463          tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_element_type);
464          tTypedPointer destination_next = destination_object.GetVectorElement(1);
465          operation.Continue(source, destination_next);
466          size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
467          for (size_t i = 2; i < size; i++)
468          {
469            tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type);
470            destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_element_type);
471            operation.Continue(source, destination_next);
472          }
473        }
474      }
475    }
476    else
477    {
478      throw std::runtime_error("Unsupported types for 'For Each' Operation");
479    }
480  }
481
482  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
483  {
484    throw std::logic_error("Not supported as single or second operation");
485  }
486} cFOR_EACH;
487
488class tArrayToVector : public tRegisteredConversionOperation
489{
490public:
491  tArrayToVector() : tRegisteredConversionOperation(util::tManagedConstCharPointer("ToVector", false), tSupportedTypeFilter::ARRAY_TO_VECTOR, tSupportedTypeFilter::ARRAY_TO_VECTOR)
492  {}
493
494  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
495  {
496    if (source_type.IsArray() && destination_type.IsListType() && source_type.GetElementType() == destination_type.GetElementType())
497    {
498      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
499    }
500    return tConversionOption();
501  }
502
503  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
504  {
505    tType inter_type = operation.compiled_operation.IntermediateType();
506    char intermediate_memory[inter_type.GetSize(true)];
507    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
508    FinalConversionFunction(source_object, *intermediate_object, operation);
509    operation.Continue(*intermediate_object, destination_object);
510  }
511
512  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
513  {
514    const tType& source_type = source_object.GetType();
515    const tType source_element_type = source_type.GetElementType();
516    size_t size = source_type.GetArraySize();
517    destination_object.ResizeVector(size);
518    if (size)
519    {
520      size_t source_element_offset = source_type.GetSize() / size;
521      tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()), source_element_type);
522      tTypedPointer destination_first = destination_object.GetVectorElement(0);
523      destination_first.DeepCopyFrom(source);
524      if (size > 1)
525      {
526        tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_element_type);
527        tTypedPointer destination_next = destination_object.GetVectorElement(1);
528        destination_next.DeepCopyFrom(source);
529        size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
530        for (size_t i = 2; i < size; i++)
531        {
532          tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type);
533          destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_next.GetType());
534          destination_next.DeepCopyFrom(source);
535        }
536      }
537    }
538  }
539} cARRAY_TO_VECTOR;
540
541class tGetTupleElement : public tRegisteredConversionOperation
542{
543public:
544  tGetTupleElement() : tRegisteredConversionOperation(util::tManagedConstCharPointer("get", false), tSupportedTypeFilter::GET_TUPLE_ELEMENT, tSupportedTypeFilter::GET_TUPLE_ELEMENT, nullptr, tParameterDefinition("Index", tDataType<unsigned int>(), true))
545  {}
546
547  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
548  {
549    unsigned int index = 0;
550    if (parameter && parameter->GetType() == tDataType<std::string>())
551    {
552      index = serialization::Deserialize<unsigned int>(parameter->GetData<std::string>());
553    }
554    else if (parameter)
555    {
556      assert(parameter->GetType() == tDataType<unsigned int>());
557      index = parameter->GetData<unsigned int>();
558    }
559    auto tuple_types = source_type.GetTupleTypes();
560    if (index < tuple_types.second && destination_type == tType(tuple_types.first[index].type_info))
561    {
562      return tConversionOption(source_type, destination_type, tuple_types.first[index].offset);
563    }
564    return tConversionOption();
565  }
566} cGET_TUPLE_ELEMENT;
567
568class tWrapByteVectorOperation : public tRegisteredConversionOperation
569{
570public:
571  tWrapByteVectorOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Wrap", false), tDataType<std::vector<uint8_t>>(), tDataType<rrlib::serialization::tMemoryBuffer>(), &cCONVERSION_OPTION)
572  {}
573
574  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
575  {
576    const std::vector<uint8_t>& vector = *source_object.Get<std::vector<uint8_t>>();
577    if (vector.size())
578    {
579      const rrlib::serialization::tMemoryBuffer buffer(const_cast<uint8_t*>(&vector[0]), vector.size());
580      operation.Continue(tTypedConstPointer(&buffer), destination_object);
581    }
582    else
583    {
584      const rrlib::serialization::tMemoryBuffer buffer(0);
585      operation.Continue(tTypedConstPointer(&buffer), destination_object);
586    }
587  }
588
589  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
590  {
591    rrlib::serialization::tMemoryBuffer& buffer = *destination_object.Get<rrlib::serialization::tMemoryBuffer>();
592    const std::vector<uint8_t>& vector = *source_object.Get<std::vector<uint8_t>>();
593    buffer = rrlib::serialization::tMemoryBuffer(const_cast<uint8_t*>(&vector[0]), vector.size());
594    //const rrlib::serialization::tMemoryBuffer temp_buffer(const_cast<uint8_t*>(&vector[0]), vector.size());
595    //buffer.CopyFrom(temp_buffer);
596  }
597
598  static constexpr tConversionOption cCONVERSION_OPTION = tConversionOption(tDataType<std::vector<uint8_t>>(), tDataType<rrlib::serialization::tMemoryBuffer>(), true, &FirstConversionFunction, &FinalConversionFunction);
599} cWRAP_BYTE_VECTOR;
600
601constexpr tConversionOption tWrapByteVectorOperation::cCONVERSION_OPTION;
602
603class tListSize : public tRegisteredConversionOperation
604{
605public:
606  tListSize() : tRegisteredConversionOperation(util::tManagedConstCharPointer("size()", false), tSupportedTypeFilter::LISTS, tDataType<size_t>())
607  {}
608
609  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
610  {
611    if (source_type.IsListType() && destination_type == tDataType<size_t>())
612    {
613      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
614    }
615    return tConversionOption();
616  }
617
618  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
619  {
620    size_t size = source_object.GetVectorSize();
621    operation.Continue(tTypedConstPointer(&size), destination_object);
622  }
623
624  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
625  {
626    (*destination_object.Get<size_t>()) = source_object.GetVectorSize();
627  }
628} cLIST_SIZE;
629
630void StringToVectorConversionFunction(const std::string& source, std::vector<char>& destination)
631{
632  destination = std::vector<char>(source.begin(), source.end());
633}
634
635void VectorToStringConversionFunction(const std::vector<char>& source, std::string& destination)
636{
637  destination = std::string(source.begin(), source.end());
638}
639
640const tVoidFunctionConversionOperation<std::string, std::vector<char>, decltype(&StringToVectorConversionFunction), &StringToVectorConversionFunction> cSTRING_TO_VECTOR("ToVector");
641const tVoidFunctionConversionOperation<std::vector<char>, std::string, decltype(&VectorToStringConversionFunction), &VectorToStringConversionFunction> cVECTOR_TO_STRING("MakeString");
642
643}
644
645const tRegisteredConversionOperation& cTO_STRING_OPERATION = cTO_STRING;
646const tRegisteredConversionOperation& cSTRING_DESERIALIZATION_OPERATION = cSTRING_DESERIALIZATION;
647const tRegisteredConversionOperation& cBINARY_SERIALIZATION_OPERATION = cBINARY_SERIALIZATION;
648const tRegisteredConversionOperation& cBINARY_DESERIALIZATION_OPERATION = cBINARY_DESERIALIZATION;
649
650const tRegisteredConversionOperation& cGET_LIST_ELEMENT_OPERATION = cGET_LIST_ELEMENT;
651const tRegisteredConversionOperation& cFOR_EACH_OPERATION = cFOR_EACH;
652const tRegisteredConversionOperation& cARRAY_TO_VECTOR_OPERATION = cARRAY_TO_VECTOR;
653const tRegisteredConversionOperation& cGET_TUPLE_ELEMENT_OPERATION = cGET_TUPLE_ELEMENT;
654
655const tRegisteredConversionOperation& cWRAP_BYTE_VECTOR_OPERATION = cWRAP_BYTE_VECTOR;
656const tRegisteredConversionOperation& cLIST_SIZE_OPERATION = cLIST_SIZE;
657const tRegisteredConversionOperation& cSTRING_TO_VECTOR_OPERATION = cSTRING_TO_VECTOR;
658const tRegisteredConversionOperation& cMAKE_STRING_OPERATION = cVECTOR_TO_STRING;
659
660
661
662//----------------------------------------------------------------------
663// End of namespace declaration
664//----------------------------------------------------------------------
665}
666}
667}
Note: See TracBrowser for help on using the repository browser.