Imported Upstream version 1.0.0
[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::OCRepresentation >
60                 : TypeDef< OC::OCRepresentation >
61             {};
62
63             template< int DEPTH, typename BASE_TYPE >
64             struct SeqType
65             {
66                 typedef std::vector< typename SeqType< DEPTH - 1, BASE_TYPE >::type > type;
67             };
68
69             template< typename BASE_TYPE >
70             struct SeqType< 0, BASE_TYPE >
71             {
72                 typedef BASE_TYPE type;
73             };
74
75             template< int DEPTH, OC::AttributeType BASE_TYPE >
76             struct OCItemType
77             {
78                 typedef typename SeqType< DEPTH,
79                                         typename OCBaseType< BASE_TYPE >::type >::type type;
80             };
81
82             template< typename T >
83             struct TypeInfo
84             {
85                 typedef T type;
86                 typedef T base_type;
87                 constexpr static size_t depth = 0;
88             };
89
90             template< typename T >
91             struct TypeInfo< std::vector< T > >
92             {
93                 typedef T type;
94                 typedef typename TypeInfo< T >::base_type base_type;
95                 constexpr static size_t depth = 1 + TypeInfo< T >::depth;
96             };
97         }
98
99         class ResourceAttributesConverter
100         {
101         private:
102             ResourceAttributesConverter() = delete;
103
104             class ResourceAttributesBuilder
105             {
106             private:
107                 template < int DEPTH >
108                 void insertItem(Detail::Int2Type< DEPTH >,
109                         const OC::OCRepresentation::AttributeItem& item)
110                 {
111                     switch (item.base_type()) {
112                         case OC::AttributeType::Null:
113                             return putValue(item.attrname(), nullptr);
114
115                         case OC::AttributeType::Integer:
116                             return insertItem< DEPTH, OC::AttributeType::Integer >(item);
117
118                         case OC::AttributeType::Double:
119                             return insertItem< DEPTH, OC::AttributeType::Double >(item);
120
121                         case OC::AttributeType::Boolean:
122                             return insertItem< DEPTH, OC::AttributeType::Boolean >(item);
123
124                         case OC::AttributeType::String:
125                             return insertItem< DEPTH, OC::AttributeType::String >(item);
126
127                         case OC::AttributeType::OCRepresentation:
128                             return insertOcRep(Detail::Int2Type< DEPTH >{ }, item);
129
130                         default:
131                             assert("There must be no another base type!");
132                     }
133                 }
134
135                 template< int DEPTH, OC::AttributeType BASE_TYPE >
136                 void insertItem(const OC::OCRepresentation::AttributeItem& item)
137                 {
138                     typedef typename Detail::OCItemType< DEPTH, BASE_TYPE >::type ItemType;
139                     putValue(item.attrname(), item.getValue< ItemType >());
140                 }
141
142                 RCSResourceAttributes insertOcRep(Detail::Int2Type< 0 >,
143                         const OC::OCRepresentation& ocRep)
144                 {
145                     return ResourceAttributesConverter::fromOCRepresentation(ocRep);
146                 }
147
148                 template< int DEPTH, typename OCREPS,
149                     typename ATTRS = typename Detail::SeqType< DEPTH, RCSResourceAttributes >::type >
150                 ATTRS insertOcRep(Detail::Int2Type< DEPTH >, const OCREPS& ocRepVec)
151                 {
152                     ATTRS result;
153
154                     for (const auto& nested : ocRepVec)
155                     {
156                         result.push_back(insertOcRep(Detail::Int2Type< DEPTH - 1 >{ }, nested));
157                     }
158
159                     return result;
160                 }
161
162                 template< int DEPTH >
163                 void insertOcRep(Detail::Int2Type< DEPTH >,
164                         const OC::OCRepresentation::AttributeItem& item)
165                 {
166                     typedef typename Detail::OCItemType< DEPTH,
167                             OC::AttributeType::OCRepresentation >::type ItemType;
168
169                     putValue(item.attrname(),
170                             insertOcRep(Detail::Int2Type< DEPTH >{ }, item.getValue< ItemType >()));
171                 }
172
173             public:
174                 ResourceAttributesBuilder() = default;
175
176                 void insertItem(const OC::OCRepresentation::AttributeItem& item)
177                 {
178                     switch (item.depth())
179                     {
180                         case 0:
181                             return insertItem(Detail::Int2Type< 0 >{ }, item);
182                         case 1:
183                             return insertItem(Detail::Int2Type< 1 >{ }, item);
184                         case 2:
185                             return insertItem(Detail::Int2Type< 2 >{ }, item);
186                         case 3:
187                             return insertItem(Detail::Int2Type< 3 >{ }, item);
188
189                         default:
190                             assert("There must be no another depth!");
191                     }
192                 }
193
194                 RCSResourceAttributes&& extract()
195                 {
196                     return std::move(m_target);
197                 }
198
199             private:
200                 template< typename T >
201                 void putValue(const std::string& key, T&& value)
202                 {
203                     m_target[key] = std::forward< T >(value);
204                 }
205
206             private:
207                 RCSResourceAttributes m_target;
208             };
209
210             class OCRepresentationBuilder
211             {
212             public:
213                 OCRepresentationBuilder() = default;
214
215                 template< typename T, typename B = typename Detail::TypeInfo< T >::base_type >
216                 typename std::enable_if< !std::is_same< B, RCSResourceAttributes >::value >::type
217                 operator()(const std::string& key, const T& value)
218                 {
219                     m_target[key] = value;
220                 }
221
222                 template< typename T, typename I = Detail::TypeInfo< T > >
223                 typename std::enable_if< std::is_same< typename I::base_type,
224                                                 RCSResourceAttributes >::value >::type
225                 operator()(const std::string& key, const T& value)
226                 {
227                     m_target[key] = convertAttributes(Detail::Int2Type< I::depth >{ }, value);
228                 }
229
230                 void operator()(const std::string& key, const std::nullptr_t&)
231                 {
232                     m_target.setNULL(key);
233                 }
234
235                 OC::OCRepresentation convertAttributes(Detail::Int2Type< 0 >,
236                         const RCSResourceAttributes& attrs)
237                 {
238                     return ResourceAttributesConverter::toOCRepresentation(attrs);
239                 }
240
241                 template< int DEPTH, typename ATTRS, typename OCREPS = typename Detail::SeqType<
242                         DEPTH, OC::OCRepresentation >::type >
243                 OCREPS convertAttributes(Detail::Int2Type< DEPTH >, const ATTRS& attrs)
244                 {
245                     OCREPS result;
246
247                     for (const auto& nested : attrs)
248                     {
249                         result.push_back(
250                                 convertAttributes(Detail::Int2Type< DEPTH - 1 >{ }, nested));
251                     }
252
253                     return result;
254                 }
255
256                 OC::OCRepresentation&& extract()
257                 {
258                     return std::move(m_target);
259                 }
260
261             private:
262                 OC::OCRepresentation m_target;
263             };
264
265         public:
266             static RCSResourceAttributes fromOCRepresentation(
267                     const OC::OCRepresentation& ocRepresentation)
268             {
269                 ResourceAttributesBuilder builder;
270
271                 for (const auto& item : ocRepresentation)
272                 {
273                     builder.insertItem(item);
274                 }
275
276                 return builder.extract();
277             }
278
279             static OC::OCRepresentation toOCRepresentation(
280                     const RCSResourceAttributes& resourceAttributes)
281             {
282                 OCRepresentationBuilder builder;
283
284                 resourceAttributes.visit(builder);
285
286                 return builder.extract();
287             }
288         };
289
290     }
291 }
292
293 #endif // COMMON_RESOURCEATTRIBUTESCONVERTER_H