Skip to content

Commit 5d419bd

Browse files
committed
working implementation for deserialization
1 parent 476424d commit 5d419bd

File tree

8 files changed

+459
-92
lines changed

8 files changed

+459
-92
lines changed

core/include/moveit/task_constructor/properties.h

Lines changed: 17 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,11 @@
4545
#include <vector>
4646
#include <functional>
4747
#include <sstream>
48-
#include <ros/serialization.h>
4948

5049
#include <moveit_task_constructor_msgs/Property.h>
5150

51+
#include "properties/serialize.hpp"
52+
5253
namespace moveit {
5354
namespace task_constructor {
5455

@@ -156,6 +157,13 @@ class Property
156157
/// serialize value using registered functions
157158
static std::string serialize(const boost::any& value);
158159
static boost::any deserialize(const std::string& type_name, const std::string& wire);
160+
161+
template <typename T>
162+
static T deserialize(const moveit_task_constructor_msgs::Property& property_msg) {
163+
PropertySerializer<T>();
164+
return boost::any_cast<T>(deserialize(property_msg.type, property_msg.value));
165+
}
166+
159167
std::string serialize() const { return serialize(value()); }
160168

161169
/// get description text
@@ -173,6 +181,12 @@ class Property
173181
/// configure initialization from source using given other property name
174182
Property& configureInitFrom(SourceFlags source, const std::string& name);
175183

184+
void fillMsg(moveit_task_constructor_msgs::Property& msg) const {
185+
msg.description = description();
186+
msg.type = typeName();
187+
msg.value = serialize();
188+
}
189+
176190
private:
177191
std::string description_;
178192
const type_info& type_info_;
@@ -185,84 +199,6 @@ class Property
185199
InitializerFunction initializer_;
186200
};
187201

188-
// hasSerialize<T>::value provides a true/false constexpr depending on whether operator<< is supported.
189-
// This uses SFINAE, extracted from https://jguegant.github.io/blogs/tech/sfinae-introduction.html
190-
template <typename T, typename = std::ostream&>
191-
struct hasSerialize : std::false_type
192-
{};
193-
194-
template <typename T>
195-
struct hasSerialize<T, decltype(std::declval<std::ostream&>() << std::declval<T>())> : std::true_type
196-
{};
197-
198-
template <typename T, typename = std::istream&>
199-
struct hasDeserialize : std::false_type
200-
{};
201-
202-
template <typename T>
203-
struct hasDeserialize<T, decltype(std::declval<std::istream&>() >> std::declval<T&>())> : std::true_type
204-
{};
205-
206-
class PropertySerializerBase
207-
{
208-
public:
209-
using SerializeFunction = std::string (*)(const boost::any&);
210-
using DeserializeFunction = boost::any (*)(const std::string&);
211-
212-
static std::string dummySerialize(const boost::any& /*unused*/) { return ""; }
213-
static boost::any dummyDeserialize(const std::string& /*unused*/) { return boost::any(); }
214-
215-
protected:
216-
static bool insert(const std::type_index& type_index, const std::string& type_name, SerializeFunction serialize,
217-
DeserializeFunction deserialize);
218-
};
219-
220-
/// utility class to register serializer/deserializer functions for a property of type T
221-
template <typename T>
222-
class PropertySerializer : protected PropertySerializerBase
223-
{
224-
public:
225-
PropertySerializer() { insert(typeid(T), typeName<T>(), &serialize, &deserialize); }
226-
227-
template <class Q = T>
228-
static typename std::enable_if<ros::message_traits::IsMessage<Q>::value, std::string>::type typeName() {
229-
return ros::message_traits::DataType<T>::value();
230-
}
231-
232-
template <class Q = T>
233-
static typename std::enable_if<!ros::message_traits::IsMessage<Q>::value, std::string>::type typeName() {
234-
return typeid(T).name();
235-
}
236-
237-
private:
238-
/** Serialization based on std::[io]stringstream */
239-
template <class Q = T>
240-
static typename std::enable_if<hasSerialize<Q>::value, std::string>::type serialize(const boost::any& value) {
241-
std::ostringstream oss;
242-
oss << boost::any_cast<T>(value);
243-
return oss.str();
244-
}
245-
template <class Q = T>
246-
static typename std::enable_if<hasSerialize<Q>::value && hasDeserialize<Q>::value, boost::any>::type
247-
deserialize(const std::string& wired) {
248-
std::istringstream iss(wired);
249-
T value;
250-
iss >> value;
251-
return value;
252-
}
253-
254-
/** No serialization available */
255-
template <class Q = T>
256-
static typename std::enable_if<!hasSerialize<Q>::value, std::string>::type serialize(const boost::any& value) {
257-
return dummySerialize(value);
258-
}
259-
template <class Q = T>
260-
static typename std::enable_if<!hasSerialize<Q>::value || !hasDeserialize<Q>::value, boost::any>::type
261-
deserialize(const std::string& wire) {
262-
return dummyDeserialize(wire);
263-
}
264-
};
265-
266202
/** PropertyMap is map of (name, Property) pairs.
267203
*
268204
* Conveniency methods are provided to setup property initialization for several
@@ -303,7 +239,8 @@ class PropertyMap
303239
Property& property(const std::string& name);
304240
const Property& property(const std::string& name) const { return const_cast<PropertyMap*>(this)->property(name); }
305241

306-
void fillMsgs(std::vector<moveit_task_constructor_msgs::Property>& msg) const;
242+
void fillMsgs(std::vector<moveit_task_constructor_msgs::Property>& msgs) const;
243+
void fromMsgs(std::vector<moveit_task_constructor_msgs::Property>& msgs);
307244

308245
using iterator = std::map<std::string, Property>::iterator;
309246
using const_iterator = std::map<std::string, Property>::const_iterator;
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/**
2+
* @file base64.h
3+
* @author Basit Ayantunde ([email protected])
4+
* @brief
5+
* @version 0.1
6+
* @date 2019-09-08
7+
*
8+
* @copyright Copyright (c) 2019
9+
*
10+
*
11+
* Licensed under the Apache License, Version 2.0 (the "License");
12+
* you may not use this file except in compliance with the License.
13+
* You may obtain a copy of the License at
14+
*
15+
* http://www.apache.org/licenses/LICENSE-2.0
16+
17+
* Unless required by applicable law or agreed to in writing, software
18+
* distributed under the License is distributed on an "AS IS" BASIS,
19+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20+
* See the License for the specific language governing permissions and
21+
* limitations under the License.
22+
*
23+
*/
24+
25+
#ifndef LAMAR_BASE64_H
26+
#define LAMAR_BASE64_H
27+
#include <cstring>
28+
#include <string>
29+
30+
namespace base64 {
31+
32+
template <typename T = char>
33+
struct Base64Chars
34+
{
35+
static constexpr T data[]{ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
36+
"abcdefghijklmnopqrstuvwxyz"
37+
"0123456789+/" };
38+
};
39+
40+
template <typename T>
41+
constexpr T Base64Chars<T>::data[];
42+
43+
template <typename T = char>
44+
inline bool is_base64(T c) {
45+
return (isalnum(c) || (c == '+') || (c == '/'));
46+
}
47+
48+
template <typename T = char>
49+
std::basic_string<T> encode(const T* bytes_to_encode, uint32_t in_len) {
50+
std::basic_string<T> ret;
51+
int i = 0;
52+
int j = 0;
53+
T char_array_3[3];
54+
T char_array_4[4];
55+
56+
while (in_len--) {
57+
char_array_3[i++] = *(bytes_to_encode++);
58+
if (i == 3) {
59+
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
60+
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
61+
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
62+
char_array_4[3] = char_array_3[2] & 0x3f;
63+
64+
for (i = 0; (i < 4); i++)
65+
ret += Base64Chars<T>::data[char_array_4[i]];
66+
i = 0;
67+
}
68+
}
69+
70+
if (i) {
71+
for (j = i; j < 3; j++)
72+
char_array_3[j] = '\0';
73+
74+
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
75+
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
76+
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
77+
char_array_4[3] = char_array_3[2] & 0x3f;
78+
79+
for (j = 0; (j < i + 1); j++)
80+
ret += Base64Chars<T>::data[char_array_4[j]];
81+
82+
while ((i++ < 3))
83+
ret += '=';
84+
}
85+
86+
return std::move(ret);
87+
}
88+
89+
template <typename T = char>
90+
std::basic_string<T> decode(const T* encoded_string, int64_t in_len) {
91+
int i = 0;
92+
int j = 0;
93+
int in_ = 0;
94+
T char_array_4[4], char_array_3[3];
95+
std::basic_string<T> ret;
96+
97+
while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
98+
char_array_4[i++] = encoded_string[in_];
99+
in_++;
100+
if (i == 4) {
101+
for (i = 0; i < 4; i++)
102+
char_array_4[i] = strchr(Base64Chars<T>::data, char_array_4[i]) - Base64Chars<T>::data;
103+
104+
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
105+
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
106+
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
107+
108+
for (i = 0; (i < 3); i++)
109+
ret += char_array_3[i];
110+
i = 0;
111+
}
112+
}
113+
114+
if (i) {
115+
for (j = i; j < 4; j++)
116+
char_array_4[j] = 0;
117+
118+
for (j = 0; j < 4; j++)
119+
char_array_4[j] = strchr(Base64Chars<T>::data, char_array_4[j]) - Base64Chars<T>::data;
120+
121+
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
122+
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
123+
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
124+
125+
for (j = 0; (j < i - 1); j++)
126+
ret += char_array_3[j];
127+
}
128+
129+
return std::move(ret);
130+
}
131+
132+
}; // namespace base64
133+
134+
#endif

0 commit comments

Comments
 (0)