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>
33 #include "ocpayload.h"
35 #include "oic_malloc.h"
36 #include "oic_string.h"
40 static const char COAP[] = "coap://";
41 static const char COAPS[] = "coaps://";
42 static const char COAP_TCP[] = "coap+tcp://";
44 void MessageContainer::setPayload(const OCPayload* rep)
53 case PAYLOAD_TYPE_REPRESENTATION:
54 setPayload(reinterpret_cast<const OCRepPayload*>(rep));
56 case PAYLOAD_TYPE_DEVICE:
57 setPayload(reinterpret_cast<const OCDevicePayload*>(rep));
59 case PAYLOAD_TYPE_PLATFORM:
60 setPayload(reinterpret_cast<const OCPlatformPayload*>(rep));
63 throw OC::OCException("Invalid Payload type in setPayload");
68 void MessageContainer::setPayload(const OCDevicePayload* payload)
70 if (payload == nullptr)
76 rep[OC_RSRVD_DEVICE_ID] = (payload->sid) ?
77 std::string(payload->sid) :
79 rep[OC_RSRVD_DEVICE_NAME] = payload->deviceName ?
80 std::string(payload->deviceName) :
82 rep[OC_RSRVD_SPEC_VERSION] = payload->specVersion ?
83 std::string(payload->specVersion) :
85 for (OCStringLL *strll = payload->dataModelVersions; strll; strll = strll->next)
87 rep.addDataModelVersion(strll->value);
89 for (OCStringLL *strll = payload->types; strll; strll = strll->next)
91 rep.addResourceType(strll->value);
93 m_reps.push_back(std::move(rep));
96 void MessageContainer::setPayload(const OCPlatformPayload* payload)
98 if (payload == nullptr)
103 OCRepresentation rep;
104 rep[OC_RSRVD_PLATFORM_ID] = payload->info.platformID ?
105 std::string(payload->info.platformID) :
107 rep[OC_RSRVD_MFG_NAME] = payload->info.manufacturerName ?
108 std::string(payload->info.manufacturerName) :
110 rep[OC_RSRVD_MFG_URL] = payload->info.manufacturerUrl ?
111 std::string(payload->info.manufacturerUrl) :
113 rep[OC_RSRVD_MODEL_NUM] = payload->info.modelNumber ?
114 std::string(payload->info.modelNumber) :
116 rep[OC_RSRVD_MFG_DATE] = payload->info.dateOfManufacture ?
117 std::string(payload->info.dateOfManufacture) :
119 rep[OC_RSRVD_PLATFORM_VERSION] = payload->info.platformVersion ?
120 std::string(payload->info.platformVersion) :
122 rep[OC_RSRVD_OS_VERSION] = payload->info.operatingSystemVersion ?
123 std::string(payload->info.operatingSystemVersion) :
125 rep[OC_RSRVD_HARDWARE_VERSION] = payload->info.hardwareVersion ?
126 std::string(payload->info.hardwareVersion) :
128 rep[OC_RSRVD_FIRMWARE_VERSION] = payload->info.firmwareVersion ?
129 std::string(payload->info.firmwareVersion) :
131 rep[OC_RSRVD_SUPPORT_URL] = payload->info.supportUrl ?
132 std::string(payload->info.supportUrl) :
134 rep[OC_RSRVD_SYSTEM_TIME] = payload->info.systemTime ?
135 std::string(payload->info.systemTime) :
138 for (OCStringLL *strll = payload->rt; strll; strll = strll->next)
140 rep.addResourceType(strll->value);
142 for (OCStringLL *strll = payload->interfaces; strll; strll = strll->next)
144 rep.addResourceInterface(strll->value);
147 m_reps.push_back(std::move(rep));
150 void MessageContainer::setPayload(const OCRepPayload* payload)
152 const OCRepPayload* pl = payload;
155 OCRepresentation cur;
159 this->addRepresentation(cur);
163 OCRepPayload* MessageContainer::getPayload() const
165 OCRepPayload* root = nullptr;
166 for(const auto& r : representations())
170 root = r.getPayload();
174 OCRepPayloadAppend(root, r.getPayload());
181 const std::vector<OCRepresentation>& MessageContainer::representations() const
186 void MessageContainer::addRepresentation(const OCRepresentation& rep)
188 m_reps.push_back(rep);
194 struct get_payload_array: boost::static_visitor<>
197 void operator()(T& /*arr*/)
199 throw std::logic_error("Invalid calc_dimensions_visitor type");
203 void operator()(std::vector<T>& arr)
206 dimensions[0] = arr.size();
209 dimTotal = calcDimTotal(dimensions);
211 array = (void*)OICMalloc(dimTotal * root_size);
213 for(size_t i = 0; i < dimensions[0]; ++i)
215 copy_to_array(arr[i], array, i);
220 void operator()(std::vector<std::vector<T>>& arr)
223 dimensions[0] = arr.size();
226 for(size_t i = 0; i < arr.size(); ++i)
228 dimensions[1] = std::max(dimensions[1], arr[i].size());
230 dimTotal = calcDimTotal(dimensions);
231 array = (void*)OICCalloc(1, dimTotal * root_size);
233 for(size_t i = 0; i < dimensions[0]; ++i)
235 for(size_t j = 0; j < dimensions[1] && j < arr[i].size(); ++j)
237 copy_to_array(arr[i][j], array, i*dimensions[1] + j);
242 void operator()(std::vector<std::vector<std::vector<T>>>& arr)
245 dimensions[0] = arr.size();
248 for(size_t i = 0; i < arr.size(); ++i)
250 dimensions[1] = std::max(dimensions[1], arr[i].size());
252 for(size_t j = 0; j < arr[i].size(); ++j)
254 dimensions[2] = std::max(dimensions[2], arr[i][j].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 for(size_t k = 0; k < dimensions[2] && k < arr[i][j].size(); ++k)
267 copy_to_array(arr[i][j][k], array,
269 dimensions[2] * dimensions[1] * i +
277 void root_size_calc()
279 root_size = sizeof(T);
283 void copy_to_array(T item, void* array, size_t pos)
285 ((T*)array)[pos] = item;
288 size_t dimensions[MAX_REP_ARRAY_DEPTH];
295 void get_payload_array::root_size_calc<int>()
297 root_size = sizeof(int64_t);
301 void get_payload_array::root_size_calc<std::string>()
303 root_size = sizeof(char*);
307 void get_payload_array::root_size_calc<OC::OCRepresentation>()
309 root_size = sizeof(OCRepPayload*);
313 void get_payload_array::copy_to_array(int item, void* array, size_t pos)
315 ((int64_t*)array)[pos] = item;
318 #if !defined(_MSC_VER)
320 void get_payload_array::copy_to_array(std::_Bit_reference br, void* array, size_t pos)
322 ((bool*)array)[pos] = static_cast<bool>(br);
327 void get_payload_array::copy_to_array(std::string item, void* array, size_t pos)
329 ((char**)array)[pos] = OICStrdup(item.c_str());
333 void get_payload_array::copy_to_array(std::string& item, void* array, size_t pos)
335 ((char**)array)[pos] = OICStrdup(item.c_str());
339 void get_payload_array::copy_to_array(const std::string& item, void* array, size_t pos)
341 ((char**)array)[pos] = OICStrdup(item.c_str());
345 void get_payload_array::copy_to_array(OC::OCRepresentation item, void* array, size_t pos)
347 ((OCRepPayload**)array)[pos] = item.getPayload();
350 void OCRepresentation::getPayloadArray(OCRepPayload* payload,
351 const OCRepresentation::AttributeItem& item) const
353 get_payload_array vis{};
354 boost::apply_visitor(vis, m_values[item.attrname()]);
357 switch(item.base_type())
359 case AttributeType::Integer:
360 OCRepPayloadSetIntArrayAsOwner(payload, item.attrname().c_str(),
364 case AttributeType::Double:
365 OCRepPayloadSetDoubleArrayAsOwner(payload, item.attrname().c_str(),
369 case AttributeType::Boolean:
370 OCRepPayloadSetBoolArrayAsOwner(payload, item.attrname().c_str(),
374 case AttributeType::String:
375 OCRepPayloadSetStringArrayAsOwner(payload, item.attrname().c_str(),
379 case AttributeType::OCRepresentation:
380 OCRepPayloadSetPropObjectArrayAsOwner(payload, item.attrname().c_str(),
381 (OCRepPayload**)vis.array, vis.dimensions);
384 throw std::logic_error(std::string("GetPayloadArray: Not Implemented") +
385 std::to_string((int)item.base_type()));
389 OCRepPayload* OCRepresentation::getPayload() const
391 OCRepPayload* root = OCRepPayloadCreate();
394 throw std::bad_alloc();
397 OCRepPayloadSetUri(root, getUri().c_str());
399 for(const std::string& type : getResourceTypes())
401 OCRepPayloadAddResourceType(root, type.c_str());
404 for(const std::string& iface : getResourceInterfaces())
406 OCRepPayloadAddInterface(root, iface.c_str());
409 for(auto& val : *this)
413 case AttributeType::Null:
414 OCRepPayloadSetNull(root, val.attrname().c_str());
416 case AttributeType::Integer:
417 OCRepPayloadSetPropInt(root, val.attrname().c_str(), static_cast<int>(val));
419 case AttributeType::Double:
420 OCRepPayloadSetPropDouble(root, val.attrname().c_str(),
421 val.getValue<double>());
423 case AttributeType::Boolean:
424 OCRepPayloadSetPropBool(root, val.attrname().c_str(), val.getValue<bool>());
426 case AttributeType::String:
427 OCRepPayloadSetPropString(root, val.attrname().c_str(),
428 static_cast<std::string>(val).c_str());
430 case AttributeType::OCRepresentation:
431 OCRepPayloadSetPropObjectAsOwner(root, val.attrname().c_str(),
432 static_cast<OCRepresentation>(val).getPayload());
434 case AttributeType::Vector:
435 getPayloadArray(root, val);
437 case AttributeType::Binary:
438 OCRepPayloadSetPropByteString(root, val.attrname().c_str(),
439 OCByteString{const_cast<uint8_t*>(val.getValue<std::vector<uint8_t>>().data()),
440 val.getValue<std::vector<uint8_t>>().size()});
443 throw std::logic_error(std::string("Getpayload: Not Implemented") +
444 std::to_string((int)val.type()));
452 size_t calcArrayDepth(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
454 if (dimensions[0] == 0)
456 throw std::logic_error("invalid calcArrayDepth");
458 else if (dimensions[1] == 0)
462 else if (dimensions[2] == 0)
473 T OCRepresentation::payload_array_helper_copy(size_t index, const OCRepPayloadValue* pl)
475 throw std::logic_error("payload_array_helper_copy: unsupported type");
478 int OCRepresentation::payload_array_helper_copy<int>(size_t index, const OCRepPayloadValue* pl)
480 return pl->arr.iArray[index];
483 double OCRepresentation::payload_array_helper_copy<double>(size_t index, const OCRepPayloadValue* pl)
485 return pl->arr.dArray[index];
488 bool OCRepresentation::payload_array_helper_copy<bool>(size_t index, const OCRepPayloadValue* pl)
490 return pl->arr.bArray[index];
493 std::string OCRepresentation::payload_array_helper_copy<std::string>(
494 size_t index, const OCRepPayloadValue* pl)
496 if (pl->arr.strArray[index])
498 return std::string(pl->arr.strArray[index]);
502 return std::string{};
506 OCRepresentation OCRepresentation::payload_array_helper_copy<OCRepresentation>(
507 size_t index, const OCRepPayloadValue* pl)
510 if (pl->arr.objArray[index])
512 r.setPayload(pl->arr.objArray[index]);
518 void OCRepresentation::payload_array_helper(const OCRepPayloadValue* pl, size_t depth)
522 std::vector<T> val(pl->arr.dimensions[0]);
524 for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
526 val[i] = payload_array_helper_copy<T>(i, pl);
528 this->setValue(std::string(pl->name), val);
532 std::vector<std::vector<T>> val(pl->arr.dimensions[0]);
533 for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
535 val[i].resize(pl->arr.dimensions[1]);
536 for(size_t j = 0; j < pl->arr.dimensions[1]; ++j)
538 val[i][j] = payload_array_helper_copy<T>(
539 i * pl->arr.dimensions[1] + j, pl);
542 this->setValue(std::string(pl->name), val);
546 std::vector<std::vector<std::vector<T>>> val(pl->arr.dimensions[0]);
547 for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
549 val[i].resize(pl->arr.dimensions[1]);
550 for(size_t j = 0; j < pl->arr.dimensions[1]; ++j)
552 val[i][j].resize(pl->arr.dimensions[2]);
553 for(size_t k = 0; k < pl->arr.dimensions[2]; ++k)
555 val[i][j][k] = payload_array_helper_copy<T>(
556 pl->arr.dimensions[2] * j +
557 pl->arr.dimensions[2] * pl->arr.dimensions[1] * i +
563 this->setValue(std::string(pl->name), val);
567 throw std::logic_error("Invalid depth in payload_array_helper");
571 void OCRepresentation::setPayloadArray(const OCRepPayloadValue* pl)
577 payload_array_helper<int>(pl, calcArrayDepth(pl->arr.dimensions));
579 case OCREP_PROP_DOUBLE:
580 payload_array_helper<double>(pl, calcArrayDepth(pl->arr.dimensions));
582 case OCREP_PROP_BOOL:
583 payload_array_helper<bool>(pl, calcArrayDepth(pl->arr.dimensions));
585 case OCREP_PROP_STRING:
586 payload_array_helper<std::string>(pl, calcArrayDepth(pl->arr.dimensions));
588 case OCREP_PROP_OBJECT:
589 payload_array_helper<OCRepresentation>(pl, calcArrayDepth(pl->arr.dimensions));
592 throw std::logic_error("setPayload array invalid type");
597 void OCRepresentation::setPayload(const OCRepPayload* pl)
601 OCStringLL* ll = pl->types;
604 addResourceType(ll->value);
611 addResourceInterface(ll->value);
615 OCRepPayloadValue* val = pl->values;
621 case OCREP_PROP_NULL:
625 setValue<int>(val->name, val->i);
627 case OCREP_PROP_DOUBLE:
628 setValue<double>(val->name, val->d);
630 case OCREP_PROP_BOOL:
631 setValue<bool>(val->name, val->b);
633 case OCREP_PROP_STRING:
634 setValue<std::string>(val->name, val->str);
636 case OCREP_PROP_OBJECT:
638 OCRepresentation cur;
639 cur.setPayload(val->obj);
640 setValue<OCRepresentation>(val->name, cur);
643 case OCREP_PROP_ARRAY:
644 setPayloadArray(val);
646 case OCREP_PROP_BYTE_STRING:
649 (val->ocByteStr.bytes, val->ocByteStr.bytes + val->ocByteStr.len)
653 throw std::logic_error(std::string("Not Implemented!") +
654 std::to_string((int)val->type));
661 void OCRepresentation::addChild(const OCRepresentation& rep)
663 m_children.push_back(rep);
666 void OCRepresentation::clearChildren()
671 const std::vector<OCRepresentation>& OCRepresentation::getChildren() const
676 void OCRepresentation::setChildren(const std::vector<OCRepresentation>& children)
678 m_children = children;
681 void OCRepresentation::setDevAddr(const OCDevAddr m_devAddr)
683 std::ostringstream ss;
684 if (m_devAddr.flags & OC_SECURE)
688 else if (m_devAddr.adapter & OC_ADAPTER_TCP)
696 if (m_devAddr.flags & OC_IP_USE_V6)
698 ss << '[' << m_devAddr.addr << ']';
702 ss << m_devAddr.addr;
706 ss << ':' << m_devAddr.port;
711 const std::string OCRepresentation::getHost() const
716 void OCRepresentation::setUri(const char* uri)
718 m_uri = uri ? uri : "";
721 void OCRepresentation::setUri(const std::string& uri)
726 std::string OCRepresentation::getUri() const
731 const std::vector<std::string>& OCRepresentation::getResourceTypes() const
733 return m_resourceTypes;
736 void OCRepresentation::setResourceTypes(const std::vector<std::string>& resourceTypes)
738 m_resourceTypes = resourceTypes;
741 void OCRepresentation::addResourceType(const std::string& str)
743 m_resourceTypes.push_back(str);
746 const std::vector<std::string>& OCRepresentation::getResourceInterfaces() const
751 void OCRepresentation::addResourceInterface(const std::string& str)
753 m_interfaces.push_back(str);
756 void OCRepresentation::setResourceInterfaces(const std::vector<std::string>& resourceInterfaces)
758 m_interfaces = resourceInterfaces;
761 const std::vector<std::string>& OCRepresentation::getDataModelVersions() const
763 return m_dataModelVersions;
766 void OCRepresentation::addDataModelVersion(const std::string& str)
768 m_dataModelVersions.push_back(str);
771 bool OCRepresentation::hasAttribute(const std::string& str) const
773 return m_values.find(str) != m_values.end();
776 bool OCRepresentation::emptyData() const
778 // This logic is meant to determine whether based on the JSON serialization rules
779 // if this object will result in empty JSON. URI is only serialized if there is valid
780 // data, ResourceType and Interfaces are only serialized if we are a nothing, a
781 // child of a default or link item.
782 // Our values array is only printed in the if we are the child of a Batch resource,
783 // the parent in a 'default' situation, or not in a child/parent relationship.
788 else if ((m_interfaceType == InterfaceType::None
789 || m_interfaceType==InterfaceType::DefaultChild
790 || m_interfaceType==InterfaceType::LinkChild)
791 && (m_resourceTypes.size()>0 || m_interfaces.size()>0
792 || m_dataModelVersions.size()>0))
796 else if ((m_interfaceType == InterfaceType::None
797 || m_interfaceType == InterfaceType::BatchChild
798 || m_interfaceType == InterfaceType::DefaultParent)
799 && m_values.size()>0)
804 if (m_children.size() > 0)
812 int OCRepresentation::numberOfAttributes() const
814 return m_values.size();
817 bool OCRepresentation::erase(const std::string& str)
819 return m_values.erase(str);
822 void OCRepresentation::setNULL(const std::string& str)
824 m_values[str] = OC::NullType();
827 bool OCRepresentation::isNULL(const std::string& str) const
829 auto x = m_values.find(str);
831 if (m_values.end() != x)
833 return x->second.which() == AttributeValueNullIndex;
837 throw OCException(OC::Exception::INVALID_ATTRIBUTE+ str);
844 std::ostream& operator <<(std::ostream& os, const AttributeType at)
848 case AttributeType::Null:
851 case AttributeType::Integer:
854 case AttributeType::Double:
857 case AttributeType::Boolean:
860 case AttributeType::String:
863 case AttributeType::OCRepresentation:
864 os << "OCRepresentation";
866 case AttributeType::Vector:
869 case AttributeType::Binary:
876 // STL Container For OCRepresentation
879 OCRepresentation::AttributeItem::AttributeItem(const std::string& name,
880 std::map<std::string, AttributeValue>& vals):
881 m_attrName(name), m_values(vals){}
883 OCRepresentation::AttributeItem OCRepresentation::operator[](const std::string& key)
885 OCRepresentation::AttributeItem attr{key, m_values};
886 return std::move(attr);
889 const OCRepresentation::AttributeItem OCRepresentation::operator[](const std::string& key) const
891 OCRepresentation::AttributeItem attr{key, m_values};
892 return std::move(attr);
895 const std::string& OCRepresentation::AttributeItem::attrname() const
900 template<typename T, typename = void>
903 // contains the actual type
905 // contains the inner most vector-type
907 // contains the AttributeType for this item
908 BOOST_STATIC_CONSTEXPR AttributeType enum_type =
909 AttributeTypeConvert<T>::type;
910 // contains the AttributeType for this base-type
911 BOOST_STATIC_CONSTEXPR AttributeType enum_base_type =
912 AttributeTypeConvert<T>::type;
913 // depth of the vector
914 BOOST_STATIC_CONSTEXPR size_t depth = 0;
920 typename std::enable_if<
921 is_vector<T>::value &&
922 !std::is_same<uint8_t, typename T::value_type>::value
927 typedef typename type_info<typename T::value_type>::base_type base_type;
928 BOOST_STATIC_CONSTEXPR AttributeType enum_type = AttributeType::Vector;
929 BOOST_STATIC_CONSTEXPR AttributeType enum_base_type =
930 type_info<typename T::value_type>::enum_base_type;
931 BOOST_STATIC_CONSTEXPR size_t depth = 1 +
932 type_info<typename T::value_type>::depth;
935 // special case for binary data, which is a std::vector<uint8_t>
937 struct type_info<std::vector<uint8_t>, void>
939 typedef std::vector<uint8_t> type;
940 typedef std::vector<uint8_t> base_type;
941 BOOST_STATIC_CONSTEXPR AttributeType enum_type = AttributeType::Binary;
942 BOOST_STATIC_CONSTEXPR AttributeType enum_base_type = AttributeType::Binary;
943 BOOST_STATIC_CONSTEXPR size_t depth = 0;
947 struct type_introspection_visitor : boost::static_visitor<>
950 AttributeType base_type;
953 type_introspection_visitor() : boost::static_visitor<>(),
954 type(AttributeType::Null), base_type(AttributeType::Null), depth(0){}
956 template <typename T>
957 void operator()(T const& /*item*/)
959 type = type_info<T>::enum_type;
960 base_type = type_info<T>::enum_base_type;
961 depth = type_info<T>::depth;
965 AttributeType OCRepresentation::AttributeItem::type() const
967 type_introspection_visitor vis;
968 boost::apply_visitor(vis, m_values[m_attrName]);
972 AttributeType OCRepresentation::AttributeItem::base_type() const
974 type_introspection_visitor vis;
975 boost::apply_visitor(vis, m_values[m_attrName]);
976 return vis.base_type;
979 size_t OCRepresentation::AttributeItem::depth() const
981 type_introspection_visitor vis;
982 boost::apply_visitor(vis, m_values[m_attrName]);
986 OCRepresentation::iterator OCRepresentation::begin()
988 return OCRepresentation::iterator(m_values.begin(), m_values);
991 OCRepresentation::const_iterator OCRepresentation::begin() const
993 return OCRepresentation::const_iterator(m_values.begin(), m_values);
996 OCRepresentation::const_iterator OCRepresentation::cbegin() const
998 return OCRepresentation::const_iterator(m_values.cbegin(), m_values);
1001 OCRepresentation::iterator OCRepresentation::end()
1003 return OCRepresentation::iterator(m_values.end(), m_values);
1006 OCRepresentation::const_iterator OCRepresentation::end() const
1008 return OCRepresentation::const_iterator(m_values.end(), m_values);
1011 OCRepresentation::const_iterator OCRepresentation::cend() const
1013 return OCRepresentation::const_iterator(m_values.cend(), m_values);
1016 size_t OCRepresentation::size() const
1018 return m_values.size();
1021 bool OCRepresentation::empty() const
1023 return m_values.empty();
1026 bool OCRepresentation::iterator::operator==(const OCRepresentation::iterator& rhs) const
1028 return m_iterator == rhs.m_iterator;
1031 bool OCRepresentation::iterator::operator!=(const OCRepresentation::iterator& rhs) const
1033 return m_iterator != rhs.m_iterator;
1036 bool OCRepresentation::const_iterator::operator==(
1037 const OCRepresentation::const_iterator& rhs) const
1039 return m_iterator == rhs.m_iterator;
1042 bool OCRepresentation::const_iterator::operator!=(
1043 const OCRepresentation::const_iterator& rhs) const
1045 return m_iterator != rhs.m_iterator;
1048 OCRepresentation::iterator::reference OCRepresentation::iterator::operator*()
1053 OCRepresentation::const_iterator::const_reference
1054 OCRepresentation::const_iterator::operator*() const
1059 OCRepresentation::iterator::pointer OCRepresentation::iterator::operator->()
1064 OCRepresentation::const_iterator::const_pointer
1065 OCRepresentation::const_iterator::operator->() const
1070 OCRepresentation::iterator& OCRepresentation::iterator::operator++()
1073 if (m_iterator != m_item.m_values.end())
1075 m_item.m_attrName = m_iterator->first;
1079 m_item.m_attrName = "";
1084 OCRepresentation::const_iterator& OCRepresentation::const_iterator::operator++()
1087 if (m_iterator != m_item.m_values.end())
1089 m_item.m_attrName = m_iterator->first;
1093 m_item.m_attrName = "";
1098 OCRepresentation::iterator OCRepresentation::iterator::operator++(int)
1100 OCRepresentation::iterator itr(*this);
1105 OCRepresentation::const_iterator OCRepresentation::const_iterator::operator++(int)
1107 OCRepresentation::const_iterator itr(*this);
1112 struct to_string_visitor : boost::static_visitor<>
1115 template <typename T>
1116 void operator()(T const& item)
1118 str = boost::lexical_cast<std::string>(item);
1121 template <typename T>
1122 void operator()(std::vector<T> const& item)
1124 to_string_visitor vis;
1125 std::ostringstream stream;
1128 for(const auto& i : item)
1131 stream << vis.str << " ";
1139 void to_string_visitor::operator()(bool const& item)
1141 str = item ? "true" : "false";
1145 void to_string_visitor::operator()(std::string const& item)
1151 void to_string_visitor::operator()(NullType const& /*item*/)
1157 void to_string_visitor::operator()(OCRepresentation const& /*item*/)
1159 str = "OC::OCRepresentation";
1162 std::string OCRepresentation::getValueToString(const std::string& key) const
1164 auto x = m_values.find(key);
1165 if (x != m_values.end())
1167 to_string_visitor vis;
1168 boost::apply_visitor(vis, x->second);
1169 return std::move(vis.str);
1175 std::string OCRepresentation::AttributeItem::getValueToString() const
1177 to_string_visitor vis;
1178 boost::apply_visitor(vis, m_values[m_attrName]);
1179 return std::move(vis.str);
1182 std::ostream& operator<<(std::ostream& os, const OCRepresentation::AttributeItem& ai)
1184 os << ai.getValueToString();