Merge "Patch 1 : Adding Arduino WiFi support. This requires updated Arduino WiFi...
[platform/upstream/iotivity.git] / include / OCProperties.h
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH 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 #ifndef __INTEL_OCPROPERTIES_H_20140708
21  #define __INTEL_OCPROPERTIES_H_20140708
22
23 #include <list>
24 #include <array>
25 #include <deque>
26 #include <vector>
27 #include <algorithm>
28 #include <functional>
29
30 #include <sstream>
31 #include <ostream>
32 #include <iostream>
33
34 #include <iterator>
35 #include <type_traits>
36
37 #include "OCException.h"
38 #include "OCPropertyTypes.h"
39
40 // Prettyprinters:
41 namespace OC { namespace OCReflect {
42
43 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_type& pt);
44 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_attribute& pa);
45 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_signature& ps);
46 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_binding& pb);
47 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property& p);
48
49 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_type_vector& pv);
50 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_vector& p);
51
52 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::method_binding& mb);
53
54 }} // namespace OC::OCReflect
55
56 // Convert from a concrete type to a property:
57 namespace OC { namespace OCReflect { namespace to_property {
58
59 OC::OCReflect::tagged_property convert(const bool& in);
60 OC::OCReflect::tagged_property convert(const int& in);
61 OC::OCReflect::tagged_property convert(const int64_t& in);
62 OC::OCReflect::tagged_property convert(const double& in);
63 OC::OCReflect::tagged_property convert(const std::string& in);
64
65 }}} // namespace OC::OCReflect::to_property
66
67 // Convert from a property to a concrete type:
68 namespace OC { namespace OCReflect { namespace from_property {
69
70 typedef OC::OCReflect::property_data::const_iterator pdci;
71 typedef std::tuple<pdci, pdci>  pd_iter_pair;
72
73 /* We need to use a struct to get around the fact that we can't partially specialize against a
74 free function's signature-- nothing else special happening here: */
75 struct conversion {
76
77 static void convert(const pd_iter_pair& in, bool& out)
78 {
79  out = static_cast<bool>(static_cast<int>(*(std::get<0>(in))));
80 }
81
82 static void convert(const pd_iter_pair& in, int64_t& out)
83 {
84  std::copy(std::get<0>(in), std::get<1>(in), reinterpret_cast<char *>(&out));
85 }
86
87 static void convert(const pd_iter_pair& in, double& out)
88 {
89  std::copy(std::get<0>(in), std::get<1>(in), reinterpret_cast<char *>(&out));
90 }
91
92 static void convert(const pd_iter_pair& in, std::string& out)
93 {
94  out.assign(std::get<0>(in), std::get<1>(in));
95 }
96
97 };
98
99 }}} // namespace OC::OCReflect::from_property
100
101 // Run-time typechecking:
102 namespace OC { namespace OCReflect {
103
104 typedef std::tuple<OC::OCReflect::property_data::const_iterator, OC::OCReflect::property_data::const_iterator>  pd_iter_tuple;
105 pd_iter_tuple consume_typecheck(const OC::OCReflect::property_type expected_pt, const OC::OCReflect::property_data& in);
106
107 }} // namespace OC::OCReflect
108
109 // Property binding factory:
110 namespace OC { namespace OCReflect {
111
112 inline OC::OCReflect::property_binding make_property_binding(const std::string& name, const OC::OCReflect::property_signature ps)
113 {
114  return OC::OCReflect::property_binding { name, ps };
115 }
116
117 inline OC::OCReflect::property_binding make_property_binding(const std::string& name, const OC::OCReflect::property_type pt, const OC::OCReflect::property_attribute pa = OC::OCReflect::property_attribute::rw)
118 {
119  return OC::OCReflect::property_binding { name, { pt, pa } };
120 }
121
122 }} // namespace OC::OCReflect
123
124 // ...probably not-so-efficent, but we want it "working" for now:
125 namespace OC { namespace OCReflect {
126
127 // ...a class just to facilitate the usual ADL trick:
128 struct make_property {
129
130 // ...work around array->bool conversion:
131 static OC::OCReflect::property apply(const char *in, const std::string& name)
132 {
133  return apply(std::string(in), name);
134 }
135
136 template <class InT>
137 static OC::OCReflect::property apply(const InT& in, const std::string& name)
138 {
139  OC::OCReflect::tagged_property  tp     { OC::OCReflect::to_property::convert(in) };
140  OC::OCReflect::property_binding npb    { OC::OCReflect::make_property_binding(name, std::get<0>(tp)) }; 
141
142  OC::OCReflect::property_data& tp_data = std::get<1>(tp);
143
144  // Encode the type, followed by the data:
145  OC::OCReflect::property_data encoded_data;
146
147  encoded_data.push_back(OC::OCReflect::map_property_type<InT>::value);
148  std::copy(std::begin(tp_data), std::end(tp_data), std::back_inserter(encoded_data));
149
150  return OC::OCReflect::property(npb, encoded_data);
151 }
152
153 }; // struct make_property
154
155 }} // namespace OC::OCReflect
156
157 namespace OC { namespace OCReflect {
158
159 template <class OutT>
160 OutT concretize(const OC::OCReflect::property_data& pd)
161 {
162  OutT ret;
163
164  OC::OCReflect::from_property::conversion::convert(
165         consume_typecheck(
166                 static_cast<OC::OCReflect::property_type>(
167                         OC::OCReflect::map_property_type<OutT>::value), pd), ret);
168
169  return ret;
170 }
171
172 template <class OutT>
173 OutT concretize(const OC::OCReflect::tagged_property& tp)
174 {
175  return concretize<OutT>(std::get<1>(tp));
176 }
177
178 template <class OutT>
179 OutT concretize(const OC::OCReflect::property& p)
180 {
181  return concretize<OutT>(std::get<1>(p));
182 }
183
184 }} // namespace OC::OCReflect
185
186 /* JFW: We are using concretize<> to fill this niche-- candidate for removal: 
187 namespace OC { namespace OCReflect {
188
189 // Runtime dynamic cast from entities to concrete types:
190 template <class OutT>
191 OutT narrow(const entity& e)
192 {
193  return OutT(); // placeholder
194 }
195
196 }} // namespace OC::OCReflect
197 */
198
199 #endif