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"
42 static const char COAP[] = "coap://";
43 static const char COAPS[] = "coaps://";
44 static const char COAP_TCP[] = "coap+tcp://";
46 void MessageContainer::setPayload(const OCPayload* rep)
55 case PAYLOAD_TYPE_REPRESENTATION:
56 setPayload(reinterpret_cast<const OCRepPayload*>(rep));
59 throw OC::OCException("Invalid Payload type in setPayload");
64 void MessageContainer::setPayload(const OCRepPayload* payload)
66 const OCRepPayload* pl = payload;
73 this->addRepresentation(cur);
77 OCRepPayload* MessageContainer::getPayload() const
79 OCRepPayload* root = nullptr;
80 for(const auto& r : representations())
84 root = r.getPayload();
88 OCRepPayloadAppend(root, r.getPayload());
95 const std::vector<OCRepresentation>& MessageContainer::representations() const
100 void MessageContainer::addRepresentation(const OCRepresentation& rep)
102 m_reps.push_back(rep);
108 struct get_payload_array: boost::static_visitor<>
111 void operator()(T& /*arr*/)
113 throw std::logic_error("Invalid calc_dimensions_visitor type");
117 void operator()(std::vector<T>& arr)
120 dimensions[0] = arr.size();
123 dimTotal = calcDimTotal(dimensions);
125 array = (void*)OICMalloc(dimTotal * root_size);
127 for(size_t i = 0; i < dimensions[0]; ++i)
129 copy_to_array(arr[i], array, i);
134 void operator()(std::vector<std::vector<T>>& arr)
137 dimensions[0] = arr.size();
140 for(size_t i = 0; i < arr.size(); ++i)
142 dimensions[1] = std::max(dimensions[1], arr[i].size());
144 dimTotal = calcDimTotal(dimensions);
145 array = (void*)OICCalloc(1, dimTotal * root_size);
147 for(size_t i = 0; i < dimensions[0]; ++i)
149 for(size_t j = 0; j < dimensions[1] && j < arr[i].size(); ++j)
151 copy_to_array(arr[i][j], array, i*dimensions[1] + j);
156 void operator()(std::vector<std::vector<std::vector<T>>>& arr)
159 dimensions[0] = arr.size();
162 for(size_t i = 0; i < arr.size(); ++i)
164 dimensions[1] = std::max(dimensions[1], arr[i].size());
166 for(size_t j = 0; j < arr[i].size(); ++j)
168 dimensions[2] = std::max(dimensions[2], arr[i][j].size());
172 dimTotal = calcDimTotal(dimensions);
173 array = (void*)OICCalloc(1, dimTotal * root_size);
175 for(size_t i = 0; i < dimensions[0]; ++i)
177 for(size_t j = 0; j < dimensions[1] && j < arr[i].size(); ++j)
179 for(size_t k = 0; k < dimensions[2] && k < arr[i][j].size(); ++k)
181 copy_to_array(arr[i][j][k], array,
183 dimensions[2] * dimensions[1] * i +
191 void root_size_calc()
193 root_size = sizeof(T);
197 void copy_to_array(T item, void* array, size_t pos)
199 ((T*)array)[pos] = item;
202 size_t dimensions[MAX_REP_ARRAY_DEPTH];
209 void get_payload_array::root_size_calc<int>()
211 root_size = sizeof(int64_t);
215 void get_payload_array::root_size_calc<std::string>()
217 root_size = sizeof(char*);
221 void get_payload_array::root_size_calc<OC::OCRepresentation>()
223 root_size = sizeof(OCRepPayload*);
227 void get_payload_array::copy_to_array(int item, void* array, size_t pos)
229 ((int64_t*)array)[pos] = item;
232 #if !defined(_MSC_VER)
234 void get_payload_array::copy_to_array(std::_Bit_reference br, void* array, size_t pos)
236 ((bool*)array)[pos] = static_cast<bool>(br);
241 void get_payload_array::copy_to_array(std::string item, void* array, size_t pos)
243 ((char**)array)[pos] = OICStrdup(item.c_str());
247 void get_payload_array::copy_to_array(std::string& item, void* array, size_t pos)
249 ((char**)array)[pos] = OICStrdup(item.c_str());
253 void get_payload_array::copy_to_array(const std::string& item, void* array, size_t pos)
255 ((char**)array)[pos] = OICStrdup(item.c_str());
259 void get_payload_array::copy_to_array(OCByteString item, void *array, size_t pos)
261 ((OCByteString *)array)[pos] = item;
265 void get_payload_array::copy_to_array(OCByteString &item, void *array, size_t pos)
267 ((OCByteString *)array)[pos] = item;
271 void get_payload_array::copy_to_array(const OCByteString &item, void *array, size_t pos)
273 ((OCByteString *)array)[pos] = item;
277 void get_payload_array::copy_to_array(OC::OCRepresentation item, void* array, size_t pos)
279 ((OCRepPayload**)array)[pos] = item.getPayload();
282 void OCRepresentation::getPayloadArray(OCRepPayload* payload,
283 const OCRepresentation::AttributeItem& item) const
285 get_payload_array vis{};
286 boost::apply_visitor(vis, m_values[item.attrname()]);
289 switch(item.base_type())
291 case AttributeType::Integer:
292 OCRepPayloadSetIntArrayAsOwner(payload, item.attrname().c_str(),
296 case AttributeType::Double:
297 OCRepPayloadSetDoubleArrayAsOwner(payload, item.attrname().c_str(),
301 case AttributeType::Boolean:
302 OCRepPayloadSetBoolArrayAsOwner(payload, item.attrname().c_str(),
306 case AttributeType::String:
307 OCRepPayloadSetStringArrayAsOwner(payload, item.attrname().c_str(),
311 case AttributeType::OCByteString:
312 OCRepPayloadSetByteStringArrayAsOwner(payload, item.attrname().c_str(),
313 (OCByteString *)vis.array, vis.dimensions);
315 case AttributeType::OCRepresentation:
316 OCRepPayloadSetPropObjectArrayAsOwner(payload, item.attrname().c_str(),
317 (OCRepPayload**)vis.array, vis.dimensions);
320 throw std::logic_error(std::string("GetPayloadArray: Not Implemented") +
321 std::to_string((int)item.base_type()));
325 OCRepPayload* OCRepresentation::getPayload() const
327 OCRepPayload* root = OCRepPayloadCreate();
330 throw std::bad_alloc();
333 OCRepPayloadSetUri(root, getUri().c_str());
335 for(const std::string& type : getResourceTypes())
337 OCRepPayloadAddResourceType(root, type.c_str());
340 for(const std::string& iface : getResourceInterfaces())
342 OCRepPayloadAddInterface(root, iface.c_str());
345 for(auto& val : *this)
349 case AttributeType::Null:
350 OCRepPayloadSetNull(root, val.attrname().c_str());
352 case AttributeType::Integer:
353 OCRepPayloadSetPropInt(root, val.attrname().c_str(), static_cast<int>(val));
355 case AttributeType::Double:
356 OCRepPayloadSetPropDouble(root, val.attrname().c_str(),
357 val.getValue<double>());
359 case AttributeType::Boolean:
360 OCRepPayloadSetPropBool(root, val.attrname().c_str(), val.getValue<bool>());
362 case AttributeType::String:
363 OCRepPayloadSetPropString(root, val.attrname().c_str(),
364 static_cast<std::string>(val).c_str());
366 case AttributeType::OCByteString:
367 OCRepPayloadSetPropByteString(root, val.attrname().c_str(), val.getValue<OCByteString>());
369 case AttributeType::OCRepresentation:
370 OCRepPayloadSetPropObjectAsOwner(root, val.attrname().c_str(),
371 static_cast<OCRepresentation>(val).getPayload());
373 case AttributeType::Vector:
374 getPayloadArray(root, val);
376 case AttributeType::Binary:
377 OCRepPayloadSetPropByteString(root, val.attrname().c_str(),
378 OCByteString{const_cast<uint8_t*>(val.getValue<std::vector<uint8_t>>().data()),
379 val.getValue<std::vector<uint8_t>>().size()});
382 throw std::logic_error(std::string("Getpayload: Not Implemented") +
383 std::to_string((int)val.type()));
391 size_t calcArrayDepth(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
393 if (dimensions[0] == 0)
395 throw std::logic_error("invalid calcArrayDepth");
397 else if (dimensions[1] == 0)
401 else if (dimensions[2] == 0)
412 T OCRepresentation::payload_array_helper_copy(size_t index, const OCRepPayloadValue* pl)
414 throw std::logic_error("payload_array_helper_copy: unsupported type");
417 int OCRepresentation::payload_array_helper_copy<int>(size_t index, const OCRepPayloadValue* pl)
419 return pl->arr.iArray[index];
422 double OCRepresentation::payload_array_helper_copy<double>(size_t index, const OCRepPayloadValue* pl)
424 return pl->arr.dArray[index];
427 bool OCRepresentation::payload_array_helper_copy<bool>(size_t index, const OCRepPayloadValue* pl)
429 return pl->arr.bArray[index];
432 std::string OCRepresentation::payload_array_helper_copy<std::string>(
433 size_t index, const OCRepPayloadValue* pl)
435 if (pl->arr.strArray[index])
437 return std::string(pl->arr.strArray[index]);
441 return std::string{};
446 OCByteString OCRepresentation::payload_array_helper_copy<OCByteString>(
447 size_t index, const OCRepPayloadValue *pl)
449 OCByteString result {NULL, 0};
450 if (pl->arr.ocByteStrArray[index].len)
452 result = (pl->arr.ocByteStrArray[index]);
458 OCRepresentation OCRepresentation::payload_array_helper_copy<OCRepresentation>(
459 size_t index, const OCRepPayloadValue* pl)
462 if (pl->arr.objArray[index])
464 r.setPayload(pl->arr.objArray[index]);
470 void OCRepresentation::payload_array_helper(const OCRepPayloadValue* pl, size_t depth)
474 std::vector<T> val(pl->arr.dimensions[0]);
476 for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
478 val[i] = payload_array_helper_copy<T>(i, pl);
480 this->setValue(std::string(pl->name), val);
484 std::vector<std::vector<T>> val(pl->arr.dimensions[0]);
485 for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
487 val[i].resize(pl->arr.dimensions[1]);
488 for(size_t j = 0; j < pl->arr.dimensions[1]; ++j)
490 val[i][j] = payload_array_helper_copy<T>(
491 i * pl->arr.dimensions[1] + j, pl);
494 this->setValue(std::string(pl->name), val);
498 std::vector<std::vector<std::vector<T>>> val(pl->arr.dimensions[0]);
499 for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
501 val[i].resize(pl->arr.dimensions[1]);
502 for(size_t j = 0; j < pl->arr.dimensions[1]; ++j)
504 val[i][j].resize(pl->arr.dimensions[2]);
505 for(size_t k = 0; k < pl->arr.dimensions[2]; ++k)
507 val[i][j][k] = payload_array_helper_copy<T>(
508 pl->arr.dimensions[2] * j +
509 pl->arr.dimensions[2] * pl->arr.dimensions[1] * i +
515 this->setValue(std::string(pl->name), val);
519 throw std::logic_error("Invalid depth in payload_array_helper");
523 void OCRepresentation::setPayloadArray(const OCRepPayloadValue* pl)
529 payload_array_helper<int>(pl, calcArrayDepth(pl->arr.dimensions));
531 case OCREP_PROP_DOUBLE:
532 payload_array_helper<double>(pl, calcArrayDepth(pl->arr.dimensions));
534 case OCREP_PROP_BOOL:
535 payload_array_helper<bool>(pl, calcArrayDepth(pl->arr.dimensions));
537 case OCREP_PROP_STRING:
538 payload_array_helper<std::string>(pl, calcArrayDepth(pl->arr.dimensions));
540 case OCREP_PROP_BYTE_STRING:
541 payload_array_helper<OCByteString>(pl, calcArrayDepth(pl->arr.dimensions));
543 case OCREP_PROP_OBJECT:
544 payload_array_helper<OCRepresentation>(pl, calcArrayDepth(pl->arr.dimensions));
547 throw std::logic_error("setPayload array invalid type");
552 void OCRepresentation::setPayload(const OCRepPayload* pl)
556 OCStringLL* ll = pl->types;
559 addResourceType(ll->value);
566 addResourceInterface(ll->value);
570 OCRepPayloadValue* val = pl->values;
576 case OCREP_PROP_NULL:
580 setValue<int>(val->name, val->i);
582 case OCREP_PROP_DOUBLE:
583 setValue<double>(val->name, val->d);
585 case OCREP_PROP_BOOL:
586 setValue<bool>(val->name, val->b);
588 case OCREP_PROP_STRING:
589 setValue<std::string>(val->name, val->str);
591 case OCREP_PROP_OBJECT:
593 OCRepresentation cur;
594 cur.setPayload(val->obj);
595 setValue<OCRepresentation>(val->name, cur);
598 case OCREP_PROP_ARRAY:
599 setPayloadArray(val);
601 case OCREP_PROP_BYTE_STRING:
604 (val->ocByteStr.bytes, val->ocByteStr.bytes + val->ocByteStr.len)
608 throw std::logic_error(std::string("Not Implemented!") +
609 std::to_string((int)val->type));
616 void OCRepresentation::addChild(const OCRepresentation& rep)
618 m_children.push_back(rep);
621 void OCRepresentation::clearChildren()
626 const std::vector<OCRepresentation>& OCRepresentation::getChildren() const
631 void OCRepresentation::setChildren(const std::vector<OCRepresentation>& children)
633 m_children = children;
636 void OCRepresentation::setDevAddr(const OCDevAddr m_devAddr)
638 std::ostringstream ss;
639 if (m_devAddr.flags & OC_SECURE)
643 else if (m_devAddr.adapter & OC_ADAPTER_TCP)
651 if (m_devAddr.flags & OC_IP_USE_V6)
653 char addressEncoded[128] = {0};
655 OCStackResult result = OCEncodeAddressForRFC6874(addressEncoded,
656 sizeof(addressEncoded),
658 if (OC_STACK_OK != result)
660 throw OC::OCException("Invalid address in setDevAddr");
662 ss << '[' << addressEncoded << ']';
666 ss << m_devAddr.addr;
670 ss << ':' << m_devAddr.port;
675 const std::string OCRepresentation::getHost() const
680 void OCRepresentation::setUri(const char* uri)
682 m_uri = uri ? uri : "";
685 void OCRepresentation::setUri(const std::string& uri)
690 std::string OCRepresentation::getUri() const
695 const std::vector<std::string>& OCRepresentation::getResourceTypes() const
697 return m_resourceTypes;
700 void OCRepresentation::setResourceTypes(const std::vector<std::string>& resourceTypes)
702 m_resourceTypes = resourceTypes;
705 void OCRepresentation::addResourceType(const std::string& str)
707 m_resourceTypes.push_back(str);
710 const std::vector<std::string>& OCRepresentation::getResourceInterfaces() const
715 void OCRepresentation::addResourceInterface(const std::string& str)
717 m_interfaces.push_back(str);
720 void OCRepresentation::setResourceInterfaces(const std::vector<std::string>& resourceInterfaces)
722 m_interfaces = resourceInterfaces;
725 const std::vector<std::string>& OCRepresentation::getDataModelVersions() const
727 return m_dataModelVersions;
730 void OCRepresentation::addDataModelVersion(const std::string& str)
732 m_dataModelVersions.push_back(str);
735 bool OCRepresentation::hasAttribute(const std::string& str) const
737 return m_values.find(str) != m_values.end();
740 bool OCRepresentation::emptyData() const
742 // This logic is meant to determine whether based on the JSON serialization rules
743 // if this object will result in empty JSON. URI is only serialized if there is valid
744 // data, ResourceType and Interfaces are only serialized if we are a nothing, a
745 // child of a default or link item.
746 // Our values array is only printed in the if we are the child of a Batch resource,
747 // the parent in a 'default' situation, or not in a child/parent relationship.
752 else if ((m_interfaceType == InterfaceType::None
753 || m_interfaceType==InterfaceType::DefaultChild
754 || m_interfaceType==InterfaceType::LinkChild)
755 && (m_resourceTypes.size()>0 || m_interfaces.size()>0
756 || m_dataModelVersions.size()>0))
760 else if ((m_interfaceType == InterfaceType::None
761 || m_interfaceType == InterfaceType::BatchChild
762 || m_interfaceType == InterfaceType::DefaultParent)
763 && m_values.size()>0)
768 if (m_children.size() > 0)
776 int OCRepresentation::numberOfAttributes() const
778 return m_values.size();
781 bool OCRepresentation::erase(const std::string& str)
783 return m_values.erase(str);
786 void OCRepresentation::setNULL(const std::string& str)
788 m_values[str] = OC::NullType();
791 bool OCRepresentation::isNULL(const std::string& str) const
793 auto x = m_values.find(str);
795 if (m_values.end() != x)
797 return x->second.which() == AttributeValueNullIndex;
801 throw OCException(OC::Exception::INVALID_ATTRIBUTE+ str);
808 std::ostream& operator <<(std::ostream& os, const AttributeType at)
812 case AttributeType::Null:
815 case AttributeType::Integer:
818 case AttributeType::Double:
821 case AttributeType::Boolean:
824 case AttributeType::String:
827 case AttributeType::OCByteString:
828 os << "OCByteString";
830 case AttributeType::OCRepresentation:
831 os << "OCRepresentation";
833 case AttributeType::Vector:
836 case AttributeType::Binary:
843 // STL Container For OCRepresentation
846 OCRepresentation::AttributeItem::AttributeItem(const std::string& name,
847 std::map<std::string, AttributeValue>& vals):
848 m_attrName(name), m_values(vals){}
850 OCRepresentation::AttributeItem OCRepresentation::operator[](const std::string& key)
852 OCRepresentation::AttributeItem attr{key, m_values};
853 return std::move(attr);
856 const OCRepresentation::AttributeItem OCRepresentation::operator[](const std::string& key) const
858 OCRepresentation::AttributeItem attr{key, m_values};
859 return std::move(attr);
862 const std::string& OCRepresentation::AttributeItem::attrname() const
867 template<typename T, typename = void>
870 // contains the actual type
872 // contains the inner most vector-type
874 // contains the AttributeType for this item
875 BOOST_STATIC_CONSTEXPR AttributeType enum_type =
876 AttributeTypeConvert<T>::type;
877 // contains the AttributeType for this base-type
878 BOOST_STATIC_CONSTEXPR AttributeType enum_base_type =
879 AttributeTypeConvert<T>::type;
880 // depth of the vector
881 BOOST_STATIC_CONSTEXPR size_t depth = 0;
887 typename std::enable_if<
888 is_vector<T>::value &&
889 !std::is_same<uint8_t, typename T::value_type>::value
894 typedef typename type_info<typename T::value_type>::base_type base_type;
895 BOOST_STATIC_CONSTEXPR AttributeType enum_type = AttributeType::Vector;
896 BOOST_STATIC_CONSTEXPR AttributeType enum_base_type =
897 type_info<typename T::value_type>::enum_base_type;
898 BOOST_STATIC_CONSTEXPR size_t depth = 1 +
899 type_info<typename T::value_type>::depth;
902 // special case for binary data, which is a std::vector<uint8_t>
904 struct type_info<std::vector<uint8_t>, void>
906 typedef std::vector<uint8_t> type;
907 typedef std::vector<uint8_t> base_type;
908 BOOST_STATIC_CONSTEXPR AttributeType enum_type = AttributeType::Binary;
909 BOOST_STATIC_CONSTEXPR AttributeType enum_base_type = AttributeType::Binary;
910 BOOST_STATIC_CONSTEXPR size_t depth = 0;
914 struct type_introspection_visitor : boost::static_visitor<>
917 AttributeType base_type;
920 type_introspection_visitor() : boost::static_visitor<>(),
921 type(AttributeType::Null), base_type(AttributeType::Null), depth(0){}
923 template <typename T>
924 void operator()(T const& /*item*/)
926 type = type_info<T>::enum_type;
927 base_type = type_info<T>::enum_base_type;
928 depth = type_info<T>::depth;
932 AttributeType OCRepresentation::AttributeItem::type() const
934 type_introspection_visitor vis;
935 boost::apply_visitor(vis, m_values[m_attrName]);
939 AttributeType OCRepresentation::AttributeItem::base_type() const
941 type_introspection_visitor vis;
942 boost::apply_visitor(vis, m_values[m_attrName]);
943 return vis.base_type;
946 size_t OCRepresentation::AttributeItem::depth() const
948 type_introspection_visitor vis;
949 boost::apply_visitor(vis, m_values[m_attrName]);
953 OCRepresentation::iterator OCRepresentation::begin()
955 return OCRepresentation::iterator(m_values.begin(), m_values);
958 OCRepresentation::const_iterator OCRepresentation::begin() const
960 return OCRepresentation::const_iterator(m_values.begin(), m_values);
963 OCRepresentation::const_iterator OCRepresentation::cbegin() const
965 return OCRepresentation::const_iterator(m_values.cbegin(), m_values);
968 OCRepresentation::iterator OCRepresentation::end()
970 return OCRepresentation::iterator(m_values.end(), m_values);
973 OCRepresentation::const_iterator OCRepresentation::end() const
975 return OCRepresentation::const_iterator(m_values.end(), m_values);
978 OCRepresentation::const_iterator OCRepresentation::cend() const
980 return OCRepresentation::const_iterator(m_values.cend(), m_values);
983 size_t OCRepresentation::size() const
985 return m_values.size();
988 bool OCRepresentation::empty() const
990 return m_values.empty();
993 bool OCRepresentation::iterator::operator==(const OCRepresentation::iterator& rhs) const
995 return m_iterator == rhs.m_iterator;
998 bool OCRepresentation::iterator::operator!=(const OCRepresentation::iterator& rhs) const
1000 return m_iterator != rhs.m_iterator;
1003 bool OCRepresentation::const_iterator::operator==(
1004 const OCRepresentation::const_iterator& rhs) const
1006 return m_iterator == rhs.m_iterator;
1009 bool OCRepresentation::const_iterator::operator!=(
1010 const OCRepresentation::const_iterator& rhs) const
1012 return m_iterator != rhs.m_iterator;
1015 OCRepresentation::iterator::reference OCRepresentation::iterator::operator*()
1020 OCRepresentation::const_iterator::const_reference
1021 OCRepresentation::const_iterator::operator*() const
1026 OCRepresentation::iterator::pointer OCRepresentation::iterator::operator->()
1031 OCRepresentation::const_iterator::const_pointer
1032 OCRepresentation::const_iterator::operator->() const
1037 OCRepresentation::iterator& OCRepresentation::iterator::operator++()
1040 if (m_iterator != m_item.m_values.end())
1042 m_item.m_attrName = m_iterator->first;
1046 m_item.m_attrName = "";
1051 OCRepresentation::const_iterator& OCRepresentation::const_iterator::operator++()
1054 if (m_iterator != m_item.m_values.end())
1056 m_item.m_attrName = m_iterator->first;
1060 m_item.m_attrName = "";
1065 OCRepresentation::iterator OCRepresentation::iterator::operator++(int)
1067 OCRepresentation::iterator itr(*this);
1072 OCRepresentation::const_iterator OCRepresentation::const_iterator::operator++(int)
1074 OCRepresentation::const_iterator itr(*this);
1079 struct to_string_visitor : boost::static_visitor<>
1082 template <typename T>
1083 void operator()(T const& item)
1085 str = boost::lexical_cast<std::string>(item);
1088 template <typename T>
1089 void operator()(std::vector<T> const& item)
1091 to_string_visitor vis;
1092 std::ostringstream stream;
1095 for(const auto& i : item)
1098 stream << vis.str << " ";
1106 void to_string_visitor::operator()(bool const& item)
1108 str = item ? "true" : "false";
1112 void to_string_visitor::operator()(std::string const& item)
1118 void to_string_visitor::operator()(NullType const& /*item*/)
1124 void to_string_visitor::operator()(std::vector<uint8_t> const &item)
1126 std::ostringstream stream;
1127 for (size_t i = 0; i < item.size(); i++ )
1129 stream << "\\x" << std::hex << (int) item[i];
1135 void to_string_visitor::operator()(OCByteString const &item)
1137 std::vector<uint8_t> v(item.bytes, item.bytes + item.len);
1142 void to_string_visitor::operator()(OCRepresentation const& /*item*/)
1144 str = "OC::OCRepresentation";
1147 std::string OCRepresentation::getValueToString(const std::string& key) const
1149 auto x = m_values.find(key);
1150 if (x != m_values.end())
1152 to_string_visitor vis;
1153 boost::apply_visitor(vis, x->second);
1154 return std::move(vis.str);
1160 std::string OCRepresentation::AttributeItem::getValueToString() const
1162 to_string_visitor vis;
1163 boost::apply_visitor(vis, m_values[m_attrName]);
1164 return std::move(vis.str);
1167 std::ostream& operator<<(std::ostream& os, const OCRepresentation::AttributeItem& ai)
1169 os << ai.getValueToString();