1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
24 * This file contains the implementation of classes and its members related
25 * to OCRepresentation.
29 #include <OCRepresentation.h>
31 #include <boost/lexical_cast.hpp>
34 #include "ocpayload.h"
36 #include "oic_malloc.h"
37 #include "oic_string.h"
41 static const char COAP[] = "coap://";
42 static const char COAPS[] = "coaps://";
43 static const char COAP_TCP[] = "coap+tcp://";
45 void MessageContainer::setPayload(const OCPayload* rep)
54 case PAYLOAD_TYPE_REPRESENTATION:
55 setPayload(reinterpret_cast<const OCRepPayload*>(rep));
57 case PAYLOAD_TYPE_DEVICE:
58 setPayload(reinterpret_cast<const OCDevicePayload*>(rep));
60 case PAYLOAD_TYPE_PLATFORM:
61 setPayload(reinterpret_cast<const OCPlatformPayload*>(rep));
65 setPayload(reinterpret_cast<const OCRDPayload*>(rep));
69 throw OC::OCException("Invalid Payload type in setPayload");
74 void MessageContainer::setPayload(const OCDevicePayload* payload)
76 if (payload == nullptr)
82 rep[OC_RSRVD_DEVICE_ID] = (payload->sid) ?
83 std::string(payload->sid) :
85 rep[OC_RSRVD_DEVICE_NAME] = payload->deviceName ?
86 std::string(payload->deviceName) :
88 rep[OC_RSRVD_SPEC_VERSION] = payload->specVersion ?
89 std::string(payload->specVersion) :
91 for (OCStringLL *strll = payload->dataModelVersions; strll; strll = strll->next)
93 rep.addDataModelVersion(strll->value);
95 for (OCStringLL *strll = payload->types; strll; strll = strll->next)
97 rep.addResourceType(strll->value);
99 m_reps.push_back(std::move(rep));
102 void MessageContainer::setPayload(const OCPlatformPayload* payload)
104 if (payload == nullptr)
109 OCRepresentation rep;
110 rep[OC_RSRVD_PLATFORM_ID] = payload->info.platformID ?
111 std::string(payload->info.platformID) :
113 rep[OC_RSRVD_MFG_NAME] = payload->info.manufacturerName ?
114 std::string(payload->info.manufacturerName) :
116 rep[OC_RSRVD_MFG_URL] = payload->info.manufacturerUrl ?
117 std::string(payload->info.manufacturerUrl) :
119 rep[OC_RSRVD_MODEL_NUM] = payload->info.modelNumber ?
120 std::string(payload->info.modelNumber) :
122 rep[OC_RSRVD_MFG_DATE] = payload->info.dateOfManufacture ?
123 std::string(payload->info.dateOfManufacture) :
125 rep[OC_RSRVD_PLATFORM_VERSION] = payload->info.platformVersion ?
126 std::string(payload->info.platformVersion) :
128 rep[OC_RSRVD_OS_VERSION] = payload->info.operatingSystemVersion ?
129 std::string(payload->info.operatingSystemVersion) :
131 rep[OC_RSRVD_HARDWARE_VERSION] = payload->info.hardwareVersion ?
132 std::string(payload->info.hardwareVersion) :
134 rep[OC_RSRVD_FIRMWARE_VERSION] = payload->info.firmwareVersion ?
135 std::string(payload->info.firmwareVersion) :
137 rep[OC_RSRVD_SUPPORT_URL] = payload->info.supportUrl ?
138 std::string(payload->info.supportUrl) :
140 rep[OC_RSRVD_SYSTEM_TIME] = payload->info.systemTime ?
141 std::string(payload->info.systemTime) :
144 for (OCStringLL *strll = payload->rt; strll; strll = strll->next)
146 rep.addResourceType(strll->value);
148 for (OCStringLL *strll = payload->interfaces; strll; strll = strll->next)
150 rep.addResourceInterface(strll->value);
153 m_reps.push_back(std::move(rep));
156 void MessageContainer::setPayload(const OCRepPayload* payload)
158 const OCRepPayload* pl = payload;
161 OCRepresentation cur;
165 this->addRepresentation(cur);
169 void MessageContainer::setPayload(const OCRDPayload* payload)
171 OCRepresentation rep;
172 rep[OC_RSRVD_DEVICE_ID] = (payload->rdPublish->tags->di.id) ?
173 std::string(reinterpret_cast<const char*>(payload->rdPublish->tags->di.id)) :
175 rep[OC_RSRVD_DEVICE_NAME] = (payload->rdPublish->tags->n.deviceName) ?
176 std::string(payload->rdPublish->tags->n.deviceName) :
178 this->addRepresentation(rep);
180 const OCLinksPayload* pl = payload->rdPublish->setLinks;
183 OCRepresentation cur;
187 this->addRepresentation(cur);
191 OCRepPayload* MessageContainer::getPayload() const
193 OCRepPayload* root = nullptr;
194 for(const auto& r : representations())
198 root = r.getPayload();
202 OCRepPayloadAppend(root, r.getPayload());
209 const std::vector<OCRepresentation>& MessageContainer::representations() const
214 void MessageContainer::addRepresentation(const OCRepresentation& rep)
216 m_reps.push_back(rep);
222 struct get_payload_array: boost::static_visitor<>
225 void operator()(T& /*arr*/)
227 throw std::logic_error("Invalid calc_dimensions_visitor type");
231 void operator()(std::vector<T>& arr)
234 dimensions[0] = arr.size();
237 dimTotal = calcDimTotal(dimensions);
239 array = (void*)OICMalloc(dimTotal * root_size);
241 for(size_t i = 0; i < dimensions[0]; ++i)
243 copy_to_array(arr[i], array, i);
248 void operator()(std::vector<std::vector<T>>& arr)
251 dimensions[0] = arr.size();
254 for(size_t i = 0; i < arr.size(); ++i)
256 dimensions[1] = std::max(dimensions[1], arr[i].size());
258 dimTotal = calcDimTotal(dimensions);
259 array = (void*)OICCalloc(1, dimTotal * root_size);
261 for(size_t i = 0; i < dimensions[0]; ++i)
263 for(size_t j = 0; j < dimensions[1] && j < arr[i].size(); ++j)
265 copy_to_array(arr[i][j], array, i*dimensions[1] + j);
270 void operator()(std::vector<std::vector<std::vector<T>>>& arr)
273 dimensions[0] = arr.size();
276 for(size_t i = 0; i < arr.size(); ++i)
278 dimensions[1] = std::max(dimensions[1], arr[i].size());
280 for(size_t j = 0; j < arr[i].size(); ++j)
282 dimensions[2] = std::max(dimensions[2], arr[i][j].size());
286 dimTotal = calcDimTotal(dimensions);
287 array = (void*)OICCalloc(1, dimTotal * root_size);
289 for(size_t i = 0; i < dimensions[0]; ++i)
291 for(size_t j = 0; j < dimensions[1] && j < arr[i].size(); ++j)
293 for(size_t k = 0; k < dimensions[2] && k < arr[i][j].size(); ++k)
295 copy_to_array(arr[i][j][k], array,
297 dimensions[2] * dimensions[1] * i +
305 void root_size_calc()
307 root_size = sizeof(T);
311 void copy_to_array(T item, void* array, size_t pos)
313 ((T*)array)[pos] = item;
316 size_t dimensions[MAX_REP_ARRAY_DEPTH];
323 void get_payload_array::root_size_calc<int>()
325 root_size = sizeof(int64_t);
329 void get_payload_array::root_size_calc<std::string>()
331 root_size = sizeof(char*);
335 void get_payload_array::root_size_calc<OC::OCRepresentation>()
337 root_size = sizeof(OCRepPayload*);
341 void get_payload_array::copy_to_array(int item, void* array, size_t pos)
343 ((int64_t*)array)[pos] = item;
346 #if !defined(_MSC_VER)
348 void get_payload_array::copy_to_array(std::_Bit_reference br, void* array, size_t pos)
350 ((bool*)array)[pos] = static_cast<bool>(br);
355 void get_payload_array::copy_to_array(std::string item, void* array, size_t pos)
357 ((char**)array)[pos] = OICStrdup(item.c_str());
361 void get_payload_array::copy_to_array(std::string& item, void* array, size_t pos)
363 ((char**)array)[pos] = OICStrdup(item.c_str());
367 void get_payload_array::copy_to_array(const std::string& item, void* array, size_t pos)
369 ((char**)array)[pos] = OICStrdup(item.c_str());
373 void get_payload_array::copy_to_array(OCByteString item, void *array, size_t pos)
375 ((OCByteString *)array)[pos] = item;
379 void get_payload_array::copy_to_array(OCByteString &item, void *array, size_t pos)
381 ((OCByteString *)array)[pos] = item;
385 void get_payload_array::copy_to_array(const OCByteString &item, void *array, size_t pos)
387 ((OCByteString *)array)[pos] = item;
391 void get_payload_array::copy_to_array(OC::OCRepresentation item, void* array, size_t pos)
393 ((OCRepPayload**)array)[pos] = item.getPayload();
396 void OCRepresentation::getPayloadArray(OCRepPayload* payload,
397 const OCRepresentation::AttributeItem& item) const
399 get_payload_array vis{};
400 boost::apply_visitor(vis, m_values[item.attrname()]);
403 switch(item.base_type())
405 case AttributeType::Integer:
406 OCRepPayloadSetIntArrayAsOwner(payload, item.attrname().c_str(),
410 case AttributeType::Double:
411 OCRepPayloadSetDoubleArrayAsOwner(payload, item.attrname().c_str(),
415 case AttributeType::Boolean:
416 OCRepPayloadSetBoolArrayAsOwner(payload, item.attrname().c_str(),
420 case AttributeType::String:
421 OCRepPayloadSetStringArrayAsOwner(payload, item.attrname().c_str(),
425 case AttributeType::OCByteString:
426 OCRepPayloadSetByteStringArrayAsOwner(payload, item.attrname().c_str(),
427 (OCByteString *)vis.array, vis.dimensions);
429 case AttributeType::OCRepresentation:
430 OCRepPayloadSetPropObjectArrayAsOwner(payload, item.attrname().c_str(),
431 (OCRepPayload**)vis.array, vis.dimensions);
434 throw std::logic_error(std::string("GetPayloadArray: Not Implemented") +
435 std::to_string((int)item.base_type()));
439 OCRepPayload* OCRepresentation::getPayload() const
441 OCRepPayload* root = OCRepPayloadCreate();
444 throw std::bad_alloc();
447 OCRepPayloadSetUri(root, getUri().c_str());
449 for(const std::string& type : getResourceTypes())
451 OCRepPayloadAddResourceType(root, type.c_str());
454 for(const std::string& iface : getResourceInterfaces())
456 OCRepPayloadAddInterface(root, iface.c_str());
459 for(auto& val : *this)
463 case AttributeType::Null:
464 OCRepPayloadSetNull(root, val.attrname().c_str());
466 case AttributeType::Integer:
467 OCRepPayloadSetPropInt(root, val.attrname().c_str(), static_cast<int>(val));
469 case AttributeType::Double:
470 OCRepPayloadSetPropDouble(root, val.attrname().c_str(),
471 val.getValue<double>());
473 case AttributeType::Boolean:
474 OCRepPayloadSetPropBool(root, val.attrname().c_str(), val.getValue<bool>());
476 case AttributeType::String:
477 OCRepPayloadSetPropString(root, val.attrname().c_str(),
478 static_cast<std::string>(val).c_str());
480 case AttributeType::OCByteString:
481 OCRepPayloadSetPropByteString(root, val.attrname().c_str(), val.getValue<OCByteString>());
483 case AttributeType::OCRepresentation:
484 OCRepPayloadSetPropObjectAsOwner(root, val.attrname().c_str(),
485 static_cast<OCRepresentation>(val).getPayload());
487 case AttributeType::Vector:
488 getPayloadArray(root, val);
490 case AttributeType::Binary:
491 OCRepPayloadSetPropByteString(root, val.attrname().c_str(),
492 OCByteString{const_cast<uint8_t*>(val.getValue<std::vector<uint8_t>>().data()),
493 val.getValue<std::vector<uint8_t>>().size()});
496 throw std::logic_error(std::string("Getpayload: Not Implemented") +
497 std::to_string((int)val.type()));
505 size_t calcArrayDepth(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
507 if (dimensions[0] == 0)
509 throw std::logic_error("invalid calcArrayDepth");
511 else if (dimensions[1] == 0)
515 else if (dimensions[2] == 0)
526 T OCRepresentation::payload_array_helper_copy(size_t index, const OCRepPayloadValue* pl)
528 throw std::logic_error("payload_array_helper_copy: unsupported type");
531 int OCRepresentation::payload_array_helper_copy<int>(size_t index, const OCRepPayloadValue* pl)
533 return pl->arr.iArray[index];
536 double OCRepresentation::payload_array_helper_copy<double>(size_t index, const OCRepPayloadValue* pl)
538 return pl->arr.dArray[index];
541 bool OCRepresentation::payload_array_helper_copy<bool>(size_t index, const OCRepPayloadValue* pl)
543 return pl->arr.bArray[index];
546 std::string OCRepresentation::payload_array_helper_copy<std::string>(
547 size_t index, const OCRepPayloadValue* pl)
549 if (pl->arr.strArray[index])
551 return std::string(pl->arr.strArray[index]);
555 return std::string{};
560 OCByteString OCRepresentation::payload_array_helper_copy<OCByteString>(
561 size_t index, const OCRepPayloadValue *pl)
563 OCByteString result {NULL, 0};
564 if (pl->arr.ocByteStrArray[index].len)
566 result = (pl->arr.ocByteStrArray[index]);
572 OCRepresentation OCRepresentation::payload_array_helper_copy<OCRepresentation>(
573 size_t index, const OCRepPayloadValue* pl)
576 if (pl->arr.objArray[index])
578 r.setPayload(pl->arr.objArray[index]);
584 void OCRepresentation::payload_array_helper(const OCRepPayloadValue* pl, size_t depth)
588 std::vector<T> val(pl->arr.dimensions[0]);
590 for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
592 val[i] = payload_array_helper_copy<T>(i, pl);
594 this->setValue(std::string(pl->name), val);
598 std::vector<std::vector<T>> val(pl->arr.dimensions[0]);
599 for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
601 val[i].resize(pl->arr.dimensions[1]);
602 for(size_t j = 0; j < pl->arr.dimensions[1]; ++j)
604 val[i][j] = payload_array_helper_copy<T>(
605 i * pl->arr.dimensions[1] + j, pl);
608 this->setValue(std::string(pl->name), val);
612 std::vector<std::vector<std::vector<T>>> val(pl->arr.dimensions[0]);
613 for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
615 val[i].resize(pl->arr.dimensions[1]);
616 for(size_t j = 0; j < pl->arr.dimensions[1]; ++j)
618 val[i][j].resize(pl->arr.dimensions[2]);
619 for(size_t k = 0; k < pl->arr.dimensions[2]; ++k)
621 val[i][j][k] = payload_array_helper_copy<T>(
622 pl->arr.dimensions[2] * j +
623 pl->arr.dimensions[2] * pl->arr.dimensions[1] * i +
629 this->setValue(std::string(pl->name), val);
633 throw std::logic_error("Invalid depth in payload_array_helper");
637 void OCRepresentation::setPayloadArray(const OCRepPayloadValue* pl)
643 payload_array_helper<int>(pl, calcArrayDepth(pl->arr.dimensions));
645 case OCREP_PROP_DOUBLE:
646 payload_array_helper<double>(pl, calcArrayDepth(pl->arr.dimensions));
648 case OCREP_PROP_BOOL:
649 payload_array_helper<bool>(pl, calcArrayDepth(pl->arr.dimensions));
651 case OCREP_PROP_STRING:
652 payload_array_helper<std::string>(pl, calcArrayDepth(pl->arr.dimensions));
654 case OCREP_PROP_BYTE_STRING:
655 payload_array_helper<OCByteString>(pl, calcArrayDepth(pl->arr.dimensions));
657 case OCREP_PROP_OBJECT:
658 payload_array_helper<OCRepresentation>(pl, calcArrayDepth(pl->arr.dimensions));
661 throw std::logic_error("setPayload array invalid type");
666 void OCRepresentation::setPayload(const OCRepPayload* pl)
670 OCStringLL* ll = pl->types;
673 addResourceType(ll->value);
680 addResourceInterface(ll->value);
684 OCRepPayloadValue* val = pl->values;
690 case OCREP_PROP_NULL:
694 setValue<int>(val->name, val->i);
696 case OCREP_PROP_DOUBLE:
697 setValue<double>(val->name, val->d);
699 case OCREP_PROP_BOOL:
700 setValue<bool>(val->name, val->b);
702 case OCREP_PROP_STRING:
703 setValue<std::string>(val->name, val->str);
705 case OCREP_PROP_OBJECT:
707 OCRepresentation cur;
708 cur.setPayload(val->obj);
709 setValue<OCRepresentation>(val->name, cur);
712 case OCREP_PROP_ARRAY:
713 setPayloadArray(val);
715 case OCREP_PROP_BYTE_STRING:
718 (val->ocByteStr.bytes, val->ocByteStr.bytes + val->ocByteStr.len)
722 throw std::logic_error(std::string("Not Implemented!") +
723 std::to_string((int)val->type));
730 void OCRepresentation::setPayload(const OCLinksPayload* pl)
734 setValue<std::string>(OC_RSRVD_HREF, pl->href);
738 setValue<std::string>(OC_RSRVD_REL, pl->rel);
740 OCStringLL* ll = pl->rt;
743 addResourceType(ll->value);
749 addResourceInterface(ll->value);
753 setValue<int>(OC_RSRVD_POLICY, pl->p);
754 setValue<int>(OC_RSRVD_INS, pl->ins);
755 setValue<int>(OC_RSRVD_TTL, pl->ttl);
758 setValue<std::string>(OC_RSRVD_TITLE, pl->title);
762 setValue<std::string>(OC_RSRVD_URI, pl->anchor);
766 void OCRepresentation::addChild(const OCRepresentation& rep)
768 m_children.push_back(rep);
771 void OCRepresentation::clearChildren()
776 const std::vector<OCRepresentation>& OCRepresentation::getChildren() const
781 void OCRepresentation::setChildren(const std::vector<OCRepresentation>& children)
783 m_children = children;
786 void OCRepresentation::setDevAddr(const OCDevAddr m_devAddr)
788 std::ostringstream ss;
789 if (m_devAddr.flags & OC_SECURE)
793 else if (m_devAddr.adapter & OC_ADAPTER_TCP)
801 if (m_devAddr.flags & OC_IP_USE_V6)
803 ss << '[' << m_devAddr.addr << ']';
807 ss << m_devAddr.addr;
811 ss << ':' << m_devAddr.port;
816 const std::string OCRepresentation::getHost() const
821 void OCRepresentation::setUri(const char* uri)
823 m_uri = uri ? uri : "";
826 void OCRepresentation::setUri(const std::string& uri)
831 std::string OCRepresentation::getUri() const
836 const std::vector<std::string>& OCRepresentation::getResourceTypes() const
838 return m_resourceTypes;
841 void OCRepresentation::setResourceTypes(const std::vector<std::string>& resourceTypes)
843 m_resourceTypes = resourceTypes;
846 void OCRepresentation::addResourceType(const std::string& str)
848 m_resourceTypes.push_back(str);
851 const std::vector<std::string>& OCRepresentation::getResourceInterfaces() const
856 void OCRepresentation::addResourceInterface(const std::string& str)
858 m_interfaces.push_back(str);
861 void OCRepresentation::setResourceInterfaces(const std::vector<std::string>& resourceInterfaces)
863 m_interfaces = resourceInterfaces;
866 const std::vector<std::string>& OCRepresentation::getDataModelVersions() const
868 return m_dataModelVersions;
871 void OCRepresentation::addDataModelVersion(const std::string& str)
873 m_dataModelVersions.push_back(str);
876 bool OCRepresentation::hasAttribute(const std::string& str) const
878 return m_values.find(str) != m_values.end();
881 bool OCRepresentation::emptyData() const
883 // This logic is meant to determine whether based on the JSON serialization rules
884 // if this object will result in empty JSON. URI is only serialized if there is valid
885 // data, ResourceType and Interfaces are only serialized if we are a nothing, a
886 // child of a default or link item.
887 // Our values array is only printed in the if we are the child of a Batch resource,
888 // the parent in a 'default' situation, or not in a child/parent relationship.
893 else if ((m_interfaceType == InterfaceType::None
894 || m_interfaceType==InterfaceType::DefaultChild
895 || m_interfaceType==InterfaceType::LinkChild)
896 && (m_resourceTypes.size()>0 || m_interfaces.size()>0
897 || m_dataModelVersions.size()>0))
901 else if ((m_interfaceType == InterfaceType::None
902 || m_interfaceType == InterfaceType::BatchChild
903 || m_interfaceType == InterfaceType::DefaultParent)
904 && m_values.size()>0)
909 if (m_children.size() > 0)
917 int OCRepresentation::numberOfAttributes() const
919 return m_values.size();
922 bool OCRepresentation::erase(const std::string& str)
924 return m_values.erase(str);
927 void OCRepresentation::setNULL(const std::string& str)
929 m_values[str] = OC::NullType();
932 bool OCRepresentation::isNULL(const std::string& str) const
934 auto x = m_values.find(str);
936 if (m_values.end() != x)
938 return x->second.which() == AttributeValueNullIndex;
942 throw OCException(OC::Exception::INVALID_ATTRIBUTE+ str);
949 std::ostream& operator <<(std::ostream& os, const AttributeType at)
953 case AttributeType::Null:
956 case AttributeType::Integer:
959 case AttributeType::Double:
962 case AttributeType::Boolean:
965 case AttributeType::String:
968 case AttributeType::OCByteString:
969 os << "OCByteString";
971 case AttributeType::OCRepresentation:
972 os << "OCRepresentation";
974 case AttributeType::Vector:
977 case AttributeType::Binary:
984 // STL Container For OCRepresentation
987 OCRepresentation::AttributeItem::AttributeItem(const std::string& name,
988 std::map<std::string, AttributeValue>& vals):
989 m_attrName(name), m_values(vals){}
991 OCRepresentation::AttributeItem OCRepresentation::operator[](const std::string& key)
993 OCRepresentation::AttributeItem attr{key, m_values};
994 return std::move(attr);
997 const OCRepresentation::AttributeItem OCRepresentation::operator[](const std::string& key) const
999 OCRepresentation::AttributeItem attr{key, m_values};
1000 return std::move(attr);
1003 const std::string& OCRepresentation::AttributeItem::attrname() const
1008 template<typename T, typename = void>
1011 // contains the actual type
1013 // contains the inner most vector-type
1014 typedef T base_type;
1015 // contains the AttributeType for this item
1016 BOOST_STATIC_CONSTEXPR AttributeType enum_type =
1017 AttributeTypeConvert<T>::type;
1018 // contains the AttributeType for this base-type
1019 BOOST_STATIC_CONSTEXPR AttributeType enum_base_type =
1020 AttributeTypeConvert<T>::type;
1021 // depth of the vector
1022 BOOST_STATIC_CONSTEXPR size_t depth = 0;
1025 template<typename T>
1028 typename std::enable_if<
1029 is_vector<T>::value &&
1030 !std::is_same<uint8_t, typename T::value_type>::value
1035 typedef typename type_info<typename T::value_type>::base_type base_type;
1036 BOOST_STATIC_CONSTEXPR AttributeType enum_type = AttributeType::Vector;
1037 BOOST_STATIC_CONSTEXPR AttributeType enum_base_type =
1038 type_info<typename T::value_type>::enum_base_type;
1039 BOOST_STATIC_CONSTEXPR size_t depth = 1 +
1040 type_info<typename T::value_type>::depth;
1043 // special case for binary data, which is a std::vector<uint8_t>
1045 struct type_info<std::vector<uint8_t>, void>
1047 typedef std::vector<uint8_t> type;
1048 typedef std::vector<uint8_t> base_type;
1049 BOOST_STATIC_CONSTEXPR AttributeType enum_type = AttributeType::Binary;
1050 BOOST_STATIC_CONSTEXPR AttributeType enum_base_type = AttributeType::Binary;
1051 BOOST_STATIC_CONSTEXPR size_t depth = 0;
1055 struct type_introspection_visitor : boost::static_visitor<>
1058 AttributeType base_type;
1061 type_introspection_visitor() : boost::static_visitor<>(),
1062 type(AttributeType::Null), base_type(AttributeType::Null), depth(0){}
1064 template <typename T>
1065 void operator()(T const& /*item*/)
1067 type = type_info<T>::enum_type;
1068 base_type = type_info<T>::enum_base_type;
1069 depth = type_info<T>::depth;
1073 AttributeType OCRepresentation::AttributeItem::type() const
1075 type_introspection_visitor vis;
1076 boost::apply_visitor(vis, m_values[m_attrName]);
1080 AttributeType OCRepresentation::AttributeItem::base_type() const
1082 type_introspection_visitor vis;
1083 boost::apply_visitor(vis, m_values[m_attrName]);
1084 return vis.base_type;
1087 size_t OCRepresentation::AttributeItem::depth() const
1089 type_introspection_visitor vis;
1090 boost::apply_visitor(vis, m_values[m_attrName]);
1094 OCRepresentation::iterator OCRepresentation::begin()
1096 return OCRepresentation::iterator(m_values.begin(), m_values);
1099 OCRepresentation::const_iterator OCRepresentation::begin() const
1101 return OCRepresentation::const_iterator(m_values.begin(), m_values);
1104 OCRepresentation::const_iterator OCRepresentation::cbegin() const
1106 return OCRepresentation::const_iterator(m_values.cbegin(), m_values);
1109 OCRepresentation::iterator OCRepresentation::end()
1111 return OCRepresentation::iterator(m_values.end(), m_values);
1114 OCRepresentation::const_iterator OCRepresentation::end() const
1116 return OCRepresentation::const_iterator(m_values.end(), m_values);
1119 OCRepresentation::const_iterator OCRepresentation::cend() const
1121 return OCRepresentation::const_iterator(m_values.cend(), m_values);
1124 size_t OCRepresentation::size() const
1126 return m_values.size();
1129 bool OCRepresentation::empty() const
1131 return m_values.empty();
1134 bool OCRepresentation::iterator::operator==(const OCRepresentation::iterator& rhs) const
1136 return m_iterator == rhs.m_iterator;
1139 bool OCRepresentation::iterator::operator!=(const OCRepresentation::iterator& rhs) const
1141 return m_iterator != rhs.m_iterator;
1144 bool OCRepresentation::const_iterator::operator==(
1145 const OCRepresentation::const_iterator& rhs) const
1147 return m_iterator == rhs.m_iterator;
1150 bool OCRepresentation::const_iterator::operator!=(
1151 const OCRepresentation::const_iterator& rhs) const
1153 return m_iterator != rhs.m_iterator;
1156 OCRepresentation::iterator::reference OCRepresentation::iterator::operator*()
1161 OCRepresentation::const_iterator::const_reference
1162 OCRepresentation::const_iterator::operator*() const
1167 OCRepresentation::iterator::pointer OCRepresentation::iterator::operator->()
1172 OCRepresentation::const_iterator::const_pointer
1173 OCRepresentation::const_iterator::operator->() const
1178 OCRepresentation::iterator& OCRepresentation::iterator::operator++()
1181 if (m_iterator != m_item.m_values.end())
1183 m_item.m_attrName = m_iterator->first;
1187 m_item.m_attrName = "";
1192 OCRepresentation::const_iterator& OCRepresentation::const_iterator::operator++()
1195 if (m_iterator != m_item.m_values.end())
1197 m_item.m_attrName = m_iterator->first;
1201 m_item.m_attrName = "";
1206 OCRepresentation::iterator OCRepresentation::iterator::operator++(int)
1208 OCRepresentation::iterator itr(*this);
1213 OCRepresentation::const_iterator OCRepresentation::const_iterator::operator++(int)
1215 OCRepresentation::const_iterator itr(*this);
1220 struct to_string_visitor : boost::static_visitor<>
1223 template <typename T>
1224 void operator()(T const& item)
1226 str = boost::lexical_cast<std::string>(item);
1229 template <typename T>
1230 void operator()(std::vector<T> const& item)
1232 to_string_visitor vis;
1233 std::ostringstream stream;
1236 for(const auto& i : item)
1239 stream << vis.str << " ";
1247 void to_string_visitor::operator()(bool const& item)
1249 str = item ? "true" : "false";
1253 void to_string_visitor::operator()(std::string const& item)
1259 void to_string_visitor::operator()(NullType const& /*item*/)
1265 void to_string_visitor::operator()(std::vector<uint8_t> const &item)
1267 std::ostringstream stream;
1268 for (size_t i = 0; i < item.size(); i++ )
1270 stream << "\\x" << std::hex << (int) item[i];
1276 void to_string_visitor::operator()(OCByteString const &item)
1278 std::vector<uint8_t> v(item.bytes, item.bytes + item.len);
1283 void to_string_visitor::operator()(OCRepresentation const& /*item*/)
1285 str = "OC::OCRepresentation";
1288 std::string OCRepresentation::getValueToString(const std::string& key) const
1290 auto x = m_values.find(key);
1291 if (x != m_values.end())
1293 to_string_visitor vis;
1294 boost::apply_visitor(vis, x->second);
1295 return std::move(vis.str);
1301 std::string OCRepresentation::AttributeItem::getValueToString() const
1303 to_string_visitor vis;
1304 boost::apply_visitor(vis, m_values[m_attrName]);
1305 return std::move(vis.str);
1308 std::ostream& operator<<(std::ostream& os, const OCRepresentation::AttributeItem& ai)
1310 os << ai.getValueToString();