Initial merge-commit of the OIC code. Should successfully do discovery for single...
[platform/upstream/iotivity.git] / OCLib / OCProperties.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Corporation All Rights Reserved.
4 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
5
6 #include "OCReflect.h"
7 #include "OCProperties.h"
8
9 using OC::OCReflect::property_type;
10
11 namespace OC { namespace OCReflect {
12
13 std::ostream& operator<<(std::ostream& os, const property_type& pt)
14 {
15  using ocpt = property_type;
16
17  switch(pt)
18  {
19     case ocpt::nil:         os << "nil";        break;
20     case ocpt::boolean:     os << "boolean";    break;
21     case ocpt::integer:     os << "integer";    break;
22     case ocpt::rational:    os << "rational";   break;
23     case ocpt::string:      os << "string";     break;
24     case ocpt::list:        os << "list";       break;
25
26         case ocpt::INVALID:             os << "INVALID";        break;
27  }
28
29  return os;
30 }
31
32 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_attribute& pa)
33 {
34  using ocpa = OC::OCReflect::property_attribute;
35
36  switch(pa)
37  {
38     case ocpa::r:   os << 'r';      break;
39     case ocpa::w:   os << 'w';      break;
40     case ocpa::rw:  os << "rw";     break;
41  }
42
43  return os;
44 }
45
46 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_signature& ps)
47 {
48  os << '(' << ps.type << ':' << ps.attribute << ')';
49  return os;
50 }
51
52 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property& p)
53 {
54  using std::get;
55
56  const auto& npb = get<0>(p);
57   const auto& npb_name = get<0>(npb);
58   const auto& npb_sig  = get<1>(npb);
59
60  const auto& pd  = std::get<1>(p);
61
62  os << "property \"" << npb_name << "\": " << npb_sig << "\"\n";
63
64  os << '\"' << npb_name << ' ' << npb_sig;
65
66  os << "\nDATA {\n";
67
68  for(const unsigned char c : pd)
69   {
70     os << static_cast<int>(c);
71
72     if(std::isprint(c))
73      os << ' ' << c;
74
75     os << '\n';
76   }
77
78  os << "}\n";
79
80  return os;
81 }
82
83 std::ostream& operator<<(std::ostream& os, const property_type_vector& ptv)
84 {
85  for(const auto& pt : ptv)
86   os << pt << "; ";
87
88  return os;
89 }
90
91 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_vector& pv)
92 {
93  for(const auto& p : pv)
94   os << p << "; ";
95
96  return os;
97 }
98
99 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_signature_vector& psv)
100 {
101  for(const auto& ps : psv)
102   os << '[' << ps.attribute << ']' << ps.type << "; ";
103
104  return os;
105 }
106
107 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::method_signature& ms)
108 {
109  os << ms.param_signatures << " -> " << ms.ret_signature;
110  return os;
111 }
112
113 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::method_binding& mb)
114 {
115  os << mb.name << " :: " << mb.signature;
116  return os;
117 }
118
119 }} // namespace OC::OCReflect
120
121 namespace OC { namespace OCReflect { namespace to_property { namespace detail {
122
123 // Convert a memory representation to bytes:
124 template <class InT>
125 OC::OCReflect::property_data static_rep(const InT& in)
126 {
127  return OC::OCReflect::property_data(reinterpret_cast<const char *>(&in),
128                                      reinterpret_cast<const char *>(&in) + sizeof(in));
129 }
130
131 // Apply a typetag to a representation:
132 template <class RepT>
133 OC::OCReflect::tagged_property tag_rep(const property_type pt, const RepT& rep)
134 {
135  return OC::OCReflect::tagged_property({ pt }, { rep });
136 }
137
138 template <class SeqIterT>
139 OC::OCReflect::tagged_property tag_rep(const property_type pt, const SeqIterT& begin, const SeqIterT& end)
140 {
141  return OC::OCReflect::tagged_property({ pt },
142                                        { begin, end });
143 }
144
145 }}}} // namespace OC::OCReflect::to_property::detail
146
147 namespace OC { namespace OCReflect { namespace to_property { 
148
149 OC::OCReflect::tagged_property convert(const bool& in)
150 {
151  return detail::tag_rep(property_type::boolean, static_cast<char>(in));
152 }
153
154 OC::OCReflect::tagged_property convert(const int64_t& in)
155 {
156  return detail::tag_rep(property_type::integer, detail::static_rep(in));
157 }
158
159 // Convenience sugar for default platform int:
160 OC::OCReflect::tagged_property convert(const int& in)
161 {
162  static_assert(sizeof(int) <= sizeof(int64_t), 
163                "conversion to int64_t may be dangerous on your platform: use int64_t explicitly");
164
165  return convert(static_cast<int64_t>(in));
166 }
167
168 OC::OCReflect::tagged_property convert(const double& in)
169 {
170  return detail::tag_rep(property_type::rational, detail::static_rep(in));
171 }
172
173 OC::OCReflect::tagged_property convert(const std::string& in)
174 {
175  return detail::tag_rep(property_type::string, 
176                         in.begin(), in.end());
177 }
178
179 }}} // namespace OC::OCReflect::to_property
180
181 pd_iter_tuple consume_typecheck(const property_type expected_pt, const OC::OCReflect::property_data& in) 
182 {
183  OC::OCReflect::property_data::const_iterator begin = in.begin();
184
185  auto found_pt = static_cast<property_type>(*begin);
186
187  std::cout << "val ept=" << (int)expected_pt << ", ept: " << (int)found_pt << '\n';
188
189  if(expected_pt != found_pt)
190   {
191     std::ostringstream os;
192     os << "type error: " << "expected " << expected_pt << ", found " << found_pt;
193     throw OC::OCReflect::reflection_exception(os.str());
194   }
195
196  return std::forward_as_tuple(++begin, in.end());
197 }
198
199