replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / resource-encapsulation / src / common / primitiveResource / include / ResourceAttributesConverter.h
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #ifndef COMMON_RESOURCEATTRIBUTESCONVERTER_H
22 #define COMMON_RESOURCEATTRIBUTESCONVERTER_H
23
24 #include <RCSResourceAttributes.h>
25
26 #include <OCRepresentation.h>
27
28 namespace OIC
29 {
30     namespace Service
31     {
32         namespace Detail
33         {
34             template< int >
35             struct Int2Type {};
36
37             template < typename T >
38             struct TypeDef
39             {
40                 typedef T type;
41             };
42
43             template< OC::AttributeType TYPE >
44             struct OCBaseType;
45
46             template< >
47             struct OCBaseType< OC::AttributeType::Integer > : TypeDef< int >{ };
48
49             template< >
50             struct OCBaseType< OC::AttributeType::Double > : TypeDef< double > { };
51
52             template< >
53             struct OCBaseType< OC::AttributeType::Boolean > : TypeDef< bool > { };
54
55             template< >
56             struct OCBaseType< OC::AttributeType::String > : TypeDef< std::string > { };
57
58             template< >
59             struct OCBaseType< OC::AttributeType::Binary > : TypeDef< RCSByteString::DataType > { };
60
61             template< >
62             struct OCBaseType< OC::AttributeType::OCByteString > : TypeDef< OCByteString > { };
63
64             template< >
65             struct OCBaseType< OC::AttributeType::OCRepresentation >
66                 : TypeDef< OC::OCRepresentation >
67             {};
68
69             template< int DEPTH, typename BASE_TYPE >
70             struct SeqType
71             {
72                 typedef std::vector< typename SeqType< DEPTH - 1, BASE_TYPE >::type > type;
73             };
74
75             template< typename BASE_TYPE >
76             struct SeqType< 0, BASE_TYPE >
77             {
78                 typedef BASE_TYPE type;
79             };
80
81             template< int DEPTH, OC::AttributeType BASE_TYPE >
82             struct OCItemType
83             {
84                 typedef typename SeqType< DEPTH,
85                                         typename OCBaseType< BASE_TYPE >::type >::type type;
86             };
87
88             template< typename T >
89             struct TypeInfo
90             {
91                 typedef T type;
92                 typedef T base_type;
93                 constexpr static size_t depth = 0;
94             };
95
96             template< typename T >
97             struct TypeInfo< std::vector< T > >
98             {
99                 typedef T type;
100                 typedef typename TypeInfo< T >::base_type base_type;
101                 constexpr static size_t depth = 1 + TypeInfo< T >::depth;
102             };
103         }
104
105         class ResourceAttributesConverter
106         {
107         private:
108             ResourceAttributesConverter() = delete;
109
110             class ResourceAttributesBuilder
111             {
112             private:
113                 template < int DEPTH >
114                 void insertItem(Detail::Int2Type< DEPTH >,
115                         const OC::OCRepresentation::AttributeItem& item)
116                 {
117                     switch (item.base_type()) {
118                         case OC::AttributeType::Null:
119                             return putValue(item.attrname(), nullptr);
120
121                         case OC::AttributeType::Integer:
122                             return insertItem< DEPTH, OC::AttributeType::Integer >(item);
123
124                         case OC::AttributeType::Double:
125                             return insertItem< DEPTH, OC::AttributeType::Double >(item);
126
127                         case OC::AttributeType::Boolean:
128                             return insertItem< DEPTH, OC::AttributeType::Boolean >(item);
129
130                         case OC::AttributeType::String:
131                             return insertItem< DEPTH, OC::AttributeType::String >(item);
132
133                         case OC::AttributeType::Binary:
134                             // OCRep support only 0-depth for binary type.
135                             // If RI changed, this line should be changed to DEPTH.
136                             return insertOcBinary< OC::AttributeType::Binary >
137                             (Detail::Int2Type< 0 >{ }, item);
138
139                         case OC::AttributeType::OCByteString:
140                             return insertOcBinary< OC::AttributeType::OCByteString >
141                             (Detail::Int2Type< DEPTH >{ }, item);
142
143                         case OC::AttributeType::OCRepresentation:
144                             return insertOcRep(Detail::Int2Type< DEPTH >{ }, item);
145
146                         default:
147                             assert("There must be no another base type!");
148                     }
149                 }
150
151                 template< int DEPTH, OC::AttributeType BASE_TYPE >
152                 void insertItem(const OC::OCRepresentation::AttributeItem& item)
153                 {
154                     typedef typename Detail::OCItemType< DEPTH, BASE_TYPE >::type ItemType;
155                     putValue(item.attrname(), item.getValue< ItemType >());
156                 }
157
158                 RCSResourceAttributes insertOcRep(Detail::Int2Type< 0 >,
159                         const OC::OCRepresentation& ocRep)
160                 {
161                     return ResourceAttributesConverter::fromOCRepresentation(ocRep);
162                 }
163
164                 template< int DEPTH, typename OCREPS,
165                     typename ATTRS = typename Detail::SeqType< DEPTH, RCSResourceAttributes >::type >
166                 ATTRS insertOcRep(Detail::Int2Type< DEPTH >, const OCREPS& ocRepVec)
167                 {
168                     ATTRS result;
169
170                     for (const auto& nested : ocRepVec)
171                     {
172                         result.push_back(insertOcRep(Detail::Int2Type< DEPTH - 1 >{ }, nested));
173                     }
174
175                     return result;
176                 }
177
178                 template< int DEPTH >
179                 void insertOcRep(Detail::Int2Type< DEPTH >,
180                         const OC::OCRepresentation::AttributeItem& item)
181                 {
182                     typedef typename Detail::OCItemType< DEPTH,
183                             OC::AttributeType::OCRepresentation >::type ItemType;
184
185                     putValue(item.attrname(),
186                             insertOcRep(Detail::Int2Type< DEPTH >{ }, item.getValue< ItemType >()));
187                 }
188
189                 template< typename OCREP >
190                 RCSByteString insertOcBinary(Detail::Int2Type< 0 >, const OCREP& ocBinary)
191                 {
192                     return RCSByteString(ocBinary);
193                 }
194
195                 template< int DEPTH, typename OCREPS,
196                     typename ATTRS = typename Detail::SeqType< DEPTH, RCSByteString >::type >
197                 ATTRS insertOcBinary(Detail::Int2Type< DEPTH >, const OCREPS& ocBinaryVec)
198                 {
199                     ATTRS result;
200
201                     for (const auto& nested : ocBinaryVec)
202                     {
203                         result.push_back(insertOcBinary(Detail::Int2Type< DEPTH - 1 >{ }, nested));
204                     }
205
206                     return result;
207                 }
208
209                 template< OC::AttributeType BASE_TYPE, int DEPTH >
210                 void insertOcBinary(Detail::Int2Type< DEPTH >,
211                         const OC::OCRepresentation::AttributeItem& item)
212                 {
213                     typedef typename Detail::OCItemType< DEPTH, BASE_TYPE >::type ItemType;
214
215                     putValue(item.attrname(),
216                              insertOcBinary(Detail::Int2Type< DEPTH >{ },
217                                             item.getValue< ItemType >()));
218                 }
219
220             public:
221                 ResourceAttributesBuilder() = default;
222
223                 void insertItem(const OC::OCRepresentation::AttributeItem& item)
224                 {
225                     switch (item.depth())
226                     {
227                         case 0:
228                             return insertItem(Detail::Int2Type< 0 >{ }, item);
229                         case 1:
230                             return insertItem(Detail::Int2Type< 1 >{ }, item);
231                         case 2:
232                             return insertItem(Detail::Int2Type< 2 >{ }, item);
233                         case 3:
234                             return insertItem(Detail::Int2Type< 3 >{ }, item);
235
236                         default:
237                             assert("There must be no another depth!");
238                     }
239                 }
240
241                 RCSResourceAttributes&& extract()
242                 {
243                     return std::move(m_target);
244                 }
245
246             private:
247                 template< typename T >
248                 void putValue(const std::string& key, T&& value)
249                 {
250                     m_target[key] = std::forward< T >(value);
251                 }
252
253             private:
254                 RCSResourceAttributes m_target;
255             };
256
257             class OCRepresentationBuilder
258             {
259             public:
260                 OCRepresentationBuilder() = default;
261
262                 template< typename T, typename B = typename Detail::TypeInfo< T >::base_type >
263                 typename std::enable_if< (
264                 !std::is_same< B, RCSResourceAttributes >::value &&
265                 !std::is_same< B, RCSByteString >::value
266                 )>::type
267                 operator()(const std::string& key, const T& value)
268                 {
269                     m_target[key] = value;
270                 }
271
272                 template< typename T, typename I = Detail::TypeInfo< T > >
273                 typename std::enable_if< std::is_same< typename I::base_type,
274                                                 RCSResourceAttributes >::value >::type
275                 operator()(const std::string& key, const T& value)
276                 {
277                     m_target[key] = convertAttributes(Detail::Int2Type< I::depth >{ }, value);
278                 }
279
280                 template< typename T, typename I = Detail::TypeInfo< T > >
281                 typename std::enable_if< std::is_same< typename I::base_type,
282                                                 RCSByteString >::value >::type
283                 operator()(const std::string& key, const T& value)
284                 {
285                     m_target[key] = convertByteString(Detail::Int2Type< I::depth >{ }, value);
286                 }
287
288                 void operator()(const std::string& key, const std::nullptr_t&)
289                 {
290                     m_target.setNULL(key);
291                 }
292
293                 OC::OCRepresentation convertAttributes(Detail::Int2Type< 0 >,
294                         const RCSResourceAttributes& attrs)
295                 {
296                     return ResourceAttributesConverter::toOCRepresentation(attrs);
297                 }
298
299                 template< int DEPTH, typename ATTRS, typename OCREPS = typename Detail::SeqType<
300                         DEPTH, OC::OCRepresentation >::type >
301                 OCREPS convertAttributes(Detail::Int2Type< DEPTH >, const ATTRS& attrs)
302                 {
303                     OCREPS result;
304
305                     for (const auto& nested : attrs)
306                     {
307                         result.push_back(
308                                 convertAttributes(Detail::Int2Type< DEPTH - 1 >{ }, nested));
309                     }
310
311                     return result;
312                 }
313
314                 OCByteString convertByteString(Detail::Int2Type< 0 >,
315                         const RCSByteString& byteString)
316                 {
317                     OCByteString blob;
318                     blob.len = byteString.size();
319                     blob.bytes = new uint8_t[blob.len];
320                     for (size_t i = 0; i < blob.len; ++i)
321                     {
322                         blob.bytes[i] = byteString[i];
323                     }
324
325                     return blob;
326                 }
327
328                 template< int DEPTH, typename ATTRS, typename OCREPS = typename Detail::SeqType<
329                         DEPTH, OCByteString >::type >
330                 OCREPS convertByteString(Detail::Int2Type< DEPTH >, const ATTRS& byteStringVec)
331                 {
332                     OCREPS result;
333
334                     for (const auto& nested : byteStringVec)
335                     {
336                         result.push_back(
337                                 convertByteString(Detail::Int2Type< DEPTH - 1 >{ }, nested));
338                     }
339
340                     return result;
341                 }
342
343                 OC::OCRepresentation&& extract()
344                 {
345                     return std::move(m_target);
346                 }
347
348             private:
349                 OC::OCRepresentation m_target;
350             };
351
352         public:
353             static RCSResourceAttributes fromOCRepresentation(
354                     const OC::OCRepresentation& ocRepresentation)
355             {
356                 ResourceAttributesBuilder builder;
357
358                 for (const auto& item : ocRepresentation)
359                 {
360                     builder.insertItem(item);
361                 }
362
363                 return builder.extract();
364             }
365
366             static OC::OCRepresentation toOCRepresentation(
367                     const RCSResourceAttributes& resourceAttributes)
368             {
369                 OCRepresentationBuilder builder;
370
371                 resourceAttributes.visit(builder);
372
373                 return builder.extract();
374             }
375         };
376
377     }
378 }
379
380 #endif // COMMON_RESOURCEATTRIBUTESCONVERTER_H