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 "iotivity_config.h"
35 #include "ocpayload.h"
36 #include "experimental/ocrandom.h"
37 #include "oic_malloc.h"
38 #include "oic_string.h"
43 static const char COAP[] = "coap://";
44 static const char COAPS[] = "coaps://";
45 static const char COAP_TCP[] = "coap+tcp://";
47 void MessageContainer::setPayload(const OCPayload* rep)
56 case PAYLOAD_TYPE_REPRESENTATION:
57 setPayload(reinterpret_cast<const OCRepPayload*>(rep));
60 throw OC::OCException("Invalid Payload type in setPayload");
65 void MessageContainer::setPayload(const OCRepPayload* payload)
67 const OCRepPayload* pl = payload;
74 this->addRepresentation(cur);
78 OCRepPayload* MessageContainer::getPayload() const
80 OCRepPayload* root = nullptr;
81 for(const auto& r : representations())
85 root = r.getPayload();
86 if (r.getInterfaceType() == InterfaceType::BatchParent)
88 root->ifType = PAYLOAD_BATCH_INTERFACE;
93 OCRepPayloadAppend(root, r.getPayload());
100 const std::vector<OCRepresentation>& MessageContainer::representations() const
105 void MessageContainer::addRepresentation(const OCRepresentation& rep)
107 m_reps.push_back(rep);
113 struct get_payload_array: boost::static_visitor<>
116 void operator()(T& /*arr*/)
118 throw std::logic_error("Invalid calc_dimensions_visitor type");
122 void operator()(std::vector<T>& arr)
125 dimensions[0] = arr.size();
128 dimTotal = calcDimTotal(dimensions);
130 m_array = (void*)OICMalloc(dimTotal * root_size);
132 for(size_t i = 0; i < dimensions[0]; ++i)
134 copy_to_array(arr[i], m_array, i);
139 void operator()(std::vector<std::vector<T>>& arr)
142 dimensions[0] = arr.size();
145 for(size_t i = 0; i < arr.size(); ++i)
147 dimensions[1] = std::max(dimensions[1], arr[i].size());
149 dimTotal = calcDimTotal(dimensions);
150 m_array = (void*)OICCalloc(1, dimTotal * root_size);
152 for(size_t i = 0; i < dimensions[0]; ++i)
154 for(size_t j = 0; j < dimensions[1] && j < arr[i].size(); ++j)
156 copy_to_array(arr[i][j], m_array, i*dimensions[1] + j);
161 void operator()(std::vector<std::vector<std::vector<T>>>& arr)
164 dimensions[0] = arr.size();
167 for(size_t i = 0; i < arr.size(); ++i)
169 dimensions[1] = std::max(dimensions[1], arr[i].size());
171 for(size_t j = 0; j < arr[i].size(); ++j)
173 dimensions[2] = std::max(dimensions[2], arr[i][j].size());
177 dimTotal = calcDimTotal(dimensions);
178 m_array = (void*)OICCalloc(1, dimTotal * root_size);
180 for(size_t i = 0; i < dimensions[0]; ++i)
182 for(size_t j = 0; j < dimensions[1] && j < arr[i].size(); ++j)
184 for(size_t k = 0; k < dimensions[2] && k < arr[i][j].size(); ++k)
186 copy_to_array(arr[i][j][k], m_array,
188 dimensions[2] * dimensions[1] * i +
196 void root_size_calc()
198 root_size = sizeof(T);
202 void copy_to_array(T item, void* array, size_t pos)
204 ((T*)array)[pos] = item;
207 size_t dimensions[MAX_REP_ARRAY_DEPTH];
214 void get_payload_array::root_size_calc<int>()
216 root_size = sizeof(int64_t);
220 void get_payload_array::root_size_calc<std::string>()
222 root_size = sizeof(char*);
226 void get_payload_array::root_size_calc<OC::OCRepresentation>()
228 root_size = sizeof(OCRepPayload*);
232 void get_payload_array::copy_to_array(int item, void* array, size_t pos)
234 ((int64_t*)array)[pos] = item;
237 #if !(defined(_MSC_VER) || defined(__APPLE__))
239 void get_payload_array::copy_to_array(std::_Bit_reference br, void* array, size_t pos)
241 ((bool*)array)[pos] = static_cast<bool>(br);
246 void get_payload_array::copy_to_array(std::string item, void* array, size_t pos)
248 ((char**)array)[pos] = OICStrdup(item.c_str());
252 void get_payload_array::copy_to_array(std::string& item, void* array, size_t pos)
254 ((char**)array)[pos] = OICStrdup(item.c_str());
258 void get_payload_array::copy_to_array(const std::string& item, void* array, size_t pos)
260 ((char**)array)[pos] = OICStrdup(item.c_str());
264 void get_payload_array::copy_to_array(OCByteString item, void *array, size_t pos)
266 ((OCByteString *)array)[pos] = item;
270 void get_payload_array::copy_to_array(OCByteString &item, void *array, size_t pos)
272 ((OCByteString *)array)[pos] = item;
276 void get_payload_array::copy_to_array(const OCByteString &item, void *array, size_t pos)
278 ((OCByteString *)array)[pos] = item;
282 void get_payload_array::copy_to_array(OC::OCRepresentation item, void* array, size_t pos)
284 ((OCRepPayload**)array)[pos] = item.getPayload();
287 void OCRepresentation::getPayloadArray(OCRepPayload* payload,
288 const OCRepresentation::AttributeItem& item) const
290 get_payload_array vis{};
291 boost::apply_visitor(vis, m_values[item.attrname()]);
294 switch(item.base_type())
296 case AttributeType::Integer:
297 OCRepPayloadSetIntArrayAsOwner(payload, item.attrname().c_str(),
298 (int64_t*)vis.m_array,
301 case AttributeType::Double:
302 OCRepPayloadSetDoubleArrayAsOwner(payload, item.attrname().c_str(),
303 (double*)vis.m_array,
306 case AttributeType::Boolean:
307 OCRepPayloadSetBoolArrayAsOwner(payload, item.attrname().c_str(),
311 case AttributeType::String:
312 OCRepPayloadSetStringArrayAsOwner(payload, item.attrname().c_str(),
316 case AttributeType::OCByteString:
317 OCRepPayloadSetByteStringArrayAsOwner(payload, item.attrname().c_str(),
318 (OCByteString *)vis.m_array, vis.dimensions);
320 case AttributeType::OCRepresentation:
321 OCRepPayloadSetPropObjectArrayAsOwner(payload, item.attrname().c_str(),
322 (OCRepPayload**)vis.m_array, vis.dimensions);
325 throw std::logic_error(std::string("GetPayloadArray: Not Implemented") +
326 std::to_string((int)item.base_type()));
330 OCRepPayload* OCRepresentation::getPayload() const
332 OCRepPayload* root = OCRepPayloadCreate();
335 throw std::bad_alloc();
338 OCRepPayloadSetUri(root, getUri().c_str());
340 for(const std::string& type : getResourceTypes())
342 OCRepPayloadAddResourceType(root, type.c_str());
345 for(const std::string& iface : getResourceInterfaces())
347 OCRepPayloadAddInterface(root, iface.c_str());
350 for(auto& val : *this)
354 case AttributeType::Null:
355 OCRepPayloadSetNull(root, val.attrname().c_str());
357 case AttributeType::Integer:
358 OCRepPayloadSetPropInt(root, val.attrname().c_str(), static_cast<int>(val));
360 case AttributeType::Double:
361 OCRepPayloadSetPropDouble(root, val.attrname().c_str(),
362 val.getValue<double>());
364 case AttributeType::Boolean:
365 OCRepPayloadSetPropBool(root, val.attrname().c_str(), val.getValue<bool>());
367 case AttributeType::String:
368 OCRepPayloadSetPropString(root, val.attrname().c_str(),
369 static_cast<std::string>(val).c_str());
371 case AttributeType::OCByteString:
372 OCRepPayloadSetPropByteString(root, val.attrname().c_str(), val.getValue<OCByteString>());
374 case AttributeType::OCRepresentation:
375 OCRepPayloadSetPropObjectAsOwner(root, val.attrname().c_str(),
376 static_cast<OCRepresentation>(val).getPayload());
378 case AttributeType::Vector:
379 getPayloadArray(root, val);
381 case AttributeType::Binary:
382 OCRepPayloadSetPropByteString(root, val.attrname().c_str(),
383 OCByteString{const_cast<uint8_t*>(val.getValue<std::vector<uint8_t>>().data()),
384 val.getValue<std::vector<uint8_t>>().size()});
387 throw std::logic_error(std::string("Getpayload: Not Implemented") +
388 std::to_string((int)val.type()));
396 void OCRepresentation::setInterfaceType(const InterfaceType& ift)
398 m_interfaceType = ift;
401 InterfaceType OCRepresentation::getInterfaceType() const
403 return m_interfaceType;
406 size_t calcArrayDepth(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
408 if (dimensions[0] == 0)
410 throw std::logic_error("invalid calcArrayDepth");
412 else if (dimensions[1] == 0)
416 else if (dimensions[2] == 0)
427 T OCRepresentation::payload_array_helper_copy(size_t index, const OCRepPayloadValue* pl)
431 throw std::logic_error("payload_array_helper_copy: unsupported type");
434 int OCRepresentation::payload_array_helper_copy<int>(size_t index, const OCRepPayloadValue* pl)
436 // Needs to be removed as part of IOT-1726 fix.
438 #pragma warning(suppress : 4244)
439 return pl->arr.iArray[index];
441 return pl->arr.iArray[index];
445 double OCRepresentation::payload_array_helper_copy<double>(size_t index, const OCRepPayloadValue* pl)
447 return pl->arr.dArray[index];
450 bool OCRepresentation::payload_array_helper_copy<bool>(size_t index, const OCRepPayloadValue* pl)
452 return pl->arr.bArray[index];
455 std::string OCRepresentation::payload_array_helper_copy<std::string>(
456 size_t index, const OCRepPayloadValue* pl)
458 if (pl && pl->arr.strArray[index])
460 return std::string(pl->arr.strArray[index]);
463 return std::string{};
467 OCByteString OCRepresentation::payload_array_helper_copy<OCByteString>(
468 size_t index, const OCRepPayloadValue *pl)
470 OCByteString result {NULL, 0};
471 if (pl->arr.ocByteStrArray[index].len)
473 result = (pl->arr.ocByteStrArray[index]);
479 OCRepresentation OCRepresentation::payload_array_helper_copy<OCRepresentation>(
480 size_t index, const OCRepPayloadValue* pl)
483 if (pl->arr.objArray[index])
485 r.setPayload(pl->arr.objArray[index]);
491 void OCRepresentation::payload_array_helper(const OCRepPayloadValue* pl, size_t depth)
495 std::vector<T> val(pl->arr.dimensions[0]);
497 for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
499 val[i] = payload_array_helper_copy<T>(i, pl);
501 this->setValue(std::string(pl->name), val);
505 std::vector<std::vector<T>> val(pl->arr.dimensions[0]);
506 for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
508 val[i].resize(pl->arr.dimensions[1]);
509 for(size_t j = 0; j < pl->arr.dimensions[1]; ++j)
511 val[i][j] = payload_array_helper_copy<T>(
512 i * pl->arr.dimensions[1] + j, pl);
515 this->setValue(std::string(pl->name), val);
519 std::vector<std::vector<std::vector<T>>> val(pl->arr.dimensions[0]);
520 for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
522 val[i].resize(pl->arr.dimensions[1]);
523 for(size_t j = 0; j < pl->arr.dimensions[1]; ++j)
525 val[i][j].resize(pl->arr.dimensions[2]);
526 for(size_t k = 0; k < pl->arr.dimensions[2]; ++k)
528 val[i][j][k] = payload_array_helper_copy<T>(
529 pl->arr.dimensions[2] * j +
530 pl->arr.dimensions[2] * pl->arr.dimensions[1] * i +
536 this->setValue(std::string(pl->name), val);
540 throw std::logic_error("Invalid depth in payload_array_helper");
544 void OCRepresentation::setPayloadArray(const OCRepPayloadValue* pl)
550 payload_array_helper<int>(pl, calcArrayDepth(pl->arr.dimensions));
552 case OCREP_PROP_DOUBLE:
553 payload_array_helper<double>(pl, calcArrayDepth(pl->arr.dimensions));
555 case OCREP_PROP_BOOL:
556 payload_array_helper<bool>(pl, calcArrayDepth(pl->arr.dimensions));
558 case OCREP_PROP_STRING:
559 payload_array_helper<std::string>(pl, calcArrayDepth(pl->arr.dimensions));
561 case OCREP_PROP_BYTE_STRING:
562 payload_array_helper<OCByteString>(pl, calcArrayDepth(pl->arr.dimensions));
564 case OCREP_PROP_OBJECT:
565 payload_array_helper<OCRepresentation>(pl, calcArrayDepth(pl->arr.dimensions));
568 throw std::logic_error("setPayload array invalid type");
573 void OCRepresentation::setPayload(const OCRepPayload* pl)
577 OCStringLL* ll = pl->types;
580 addResourceType(ll->value);
587 addResourceInterface(ll->value);
591 OCRepPayloadValue* val = pl->values;
597 case OCREP_PROP_NULL:
601 // Needs to be removed as part of IOT-1726 fix.
603 #pragma warning(suppress : 4244)
604 setValue<int>(val->name, val->i);
606 setValue<int>(val->name, val->i);
609 case OCREP_PROP_DOUBLE:
610 setValue<double>(val->name, val->d);
612 case OCREP_PROP_BOOL:
613 setValue<bool>(val->name, val->b);
615 case OCREP_PROP_STRING:
616 setValue<std::string>(val->name, val->str);
618 case OCREP_PROP_OBJECT:
620 OCRepresentation cur;
621 cur.setPayload(val->obj);
622 setValue<OCRepresentation>(val->name, cur);
625 case OCREP_PROP_ARRAY:
626 setPayloadArray(val);
628 case OCREP_PROP_BYTE_STRING:
631 (val->ocByteStr.bytes, val->ocByteStr.bytes + val->ocByteStr.len)
635 throw std::logic_error(std::string("Not Implemented!") +
636 std::to_string((int)val->type));
643 void OCRepresentation::addChild(const OCRepresentation& rep)
645 m_children.push_back(rep);
648 void OCRepresentation::clearChildren()
653 const std::vector<OCRepresentation>& OCRepresentation::getChildren() const
658 void OCRepresentation::setChildren(const std::vector<OCRepresentation>& children)
660 m_children = children;
663 void OCRepresentation::setDevAddr(const OCDevAddr& devAddr)
665 std::ostringstream ss;
666 if (devAddr.flags & OC_SECURE)
670 else if (devAddr.adapter & OC_ADAPTER_TCP)
678 if (devAddr.flags & OC_IP_USE_V6)
680 char addressEncoded[128] = {0};
682 OCStackResult result = OCEncodeAddressForRFC6874(addressEncoded,
683 sizeof(addressEncoded),
685 if (OC_STACK_OK != result)
687 throw OC::OCException("Invalid address in setDevAddr");
689 ss << '[' << addressEncoded << ']';
697 ss << ':' << devAddr.port;
702 const std::string OCRepresentation::getHost() const
707 void OCRepresentation::setUri(const char* uri)
709 m_uri = uri ? uri : "";
712 void OCRepresentation::setUri(const std::string& uri)
717 std::string OCRepresentation::getUri() const
722 const std::vector<std::string>& OCRepresentation::getResourceTypes() const
724 return m_resourceTypes;
727 void OCRepresentation::setResourceTypes(const std::vector<std::string>& resourceTypes)
729 m_resourceTypes = resourceTypes;
732 void OCRepresentation::addResourceType(const std::string& str)
734 m_resourceTypes.push_back(str);
737 const std::vector<std::string>& OCRepresentation::getResourceInterfaces() const
742 void OCRepresentation::addResourceInterface(const std::string& str)
744 m_interfaces.push_back(str);
747 void OCRepresentation::setResourceInterfaces(const std::vector<std::string>& resourceInterfaces)
749 m_interfaces = resourceInterfaces;
752 const std::vector<std::string>& OCRepresentation::getDataModelVersions() const
754 return m_dataModelVersions;
757 void OCRepresentation::addDataModelVersion(const std::string& str)
759 m_dataModelVersions.push_back(str);
762 bool OCRepresentation::hasAttribute(const std::string& str) const
764 return m_values.find(str) != m_values.end();
767 bool OCRepresentation::emptyData() const
769 // This logic is meant to determine whether based on the JSON serialization rules
770 // if this object will result in empty JSON. URI is only serialized if there is valid
771 // data, ResourceType and Interfaces are only serialized if we are a nothing, a
772 // child of a default or link item.
773 // Our values array is only printed in the if we are the child of a Batch resource,
774 // the parent in a 'default' situation, or not in a child/parent relationship.
779 else if ((m_interfaceType == InterfaceType::None
780 || m_interfaceType==InterfaceType::DefaultChild
781 || m_interfaceType==InterfaceType::LinkChild)
782 && (m_resourceTypes.size()>0 || m_interfaces.size()>0
783 || m_dataModelVersions.size()>0))
787 else if ((m_interfaceType == InterfaceType::None
788 || m_interfaceType == InterfaceType::BatchChild
789 || m_interfaceType == InterfaceType::DefaultParent)
790 && m_values.size()>0)
795 if (m_children.size() > 0)
803 size_t OCRepresentation::numberOfAttributes() const
805 return m_values.size();
808 bool OCRepresentation::erase(const std::string& str)
810 return (m_values.erase(str) > 0);
813 void OCRepresentation::setNULL(const std::string& str)
815 m_values[str] = OC::NullType();
818 bool OCRepresentation::isNULL(const std::string& str) const
820 auto x = m_values.find(str);
822 if (m_values.end() != x)
824 return x->second.which() == AttributeValueNullIndex;
828 throw OCException(OC::Exception::INVALID_ATTRIBUTE+ str);
835 std::ostream& operator <<(std::ostream& os, const AttributeType at)
839 case AttributeType::Null:
842 case AttributeType::Integer:
845 case AttributeType::Double:
848 case AttributeType::Boolean:
851 case AttributeType::String:
854 case AttributeType::OCByteString:
855 os << "OCByteString";
857 case AttributeType::OCRepresentation:
858 os << "OCRepresentation";
860 case AttributeType::Vector:
863 case AttributeType::Binary:
870 // STL Container For OCRepresentation
873 OCRepresentation::AttributeItem::AttributeItem(const std::string& name,
874 std::map<std::string, AttributeValue>& vals):
875 m_attrName(name), m_values(vals){}
877 OCRepresentation::AttributeItem OCRepresentation::operator[](const std::string& key)
879 OCRepresentation::AttributeItem attr{key, m_values};
880 return std::move(attr);
883 const OCRepresentation::AttributeItem OCRepresentation::operator[](const std::string& key) const
885 OCRepresentation::AttributeItem attr{key, m_values};
886 return std::move(attr);
889 const std::string& OCRepresentation::AttributeItem::attrname() const
894 template<typename T, typename = void>
897 // contains the actual type
899 // contains the inner most vector-type
901 // contains the AttributeType for this item
902 BOOST_STATIC_CONSTEXPR AttributeType enum_type =
903 AttributeTypeConvert<T>::type;
904 // contains the AttributeType for this base-type
905 BOOST_STATIC_CONSTEXPR AttributeType enum_base_type =
906 AttributeTypeConvert<T>::type;
907 // depth of the vector
908 BOOST_STATIC_CONSTEXPR size_t depth = 0;
914 typename std::enable_if<
915 is_vector<T>::value &&
916 !std::is_same<uint8_t, typename T::value_type>::value
921 typedef typename type_info<typename T::value_type>::base_type base_type;
922 BOOST_STATIC_CONSTEXPR AttributeType enum_type = AttributeType::Vector;
923 BOOST_STATIC_CONSTEXPR AttributeType enum_base_type =
924 type_info<typename T::value_type>::enum_base_type;
925 BOOST_STATIC_CONSTEXPR size_t depth = 1 +
926 type_info<typename T::value_type>::depth;
929 // special case for binary data, which is a std::vector<uint8_t>
931 struct type_info<std::vector<uint8_t>, void>
933 typedef std::vector<uint8_t> type;
934 typedef std::vector<uint8_t> base_type;
935 BOOST_STATIC_CONSTEXPR AttributeType enum_type = AttributeType::Binary;
936 BOOST_STATIC_CONSTEXPR AttributeType enum_base_type = AttributeType::Binary;
937 BOOST_STATIC_CONSTEXPR size_t depth = 0;
941 struct type_introspection_visitor : boost::static_visitor<>
944 AttributeType base_type;
947 type_introspection_visitor() : boost::static_visitor<>(),
948 type(AttributeType::Null), base_type(AttributeType::Null), depth(0){}
950 template <typename T>
951 void operator()(T const& /*item*/)
953 type = type_info<T>::enum_type;
954 base_type = type_info<T>::enum_base_type;
955 depth = type_info<T>::depth;
959 AttributeType OCRepresentation::AttributeItem::type() const
961 type_introspection_visitor vis;
962 boost::apply_visitor(vis, m_values[m_attrName]);
966 AttributeType OCRepresentation::AttributeItem::base_type() const
968 type_introspection_visitor vis;
969 boost::apply_visitor(vis, m_values[m_attrName]);
970 return vis.base_type;
973 size_t OCRepresentation::AttributeItem::depth() const
975 type_introspection_visitor vis;
976 boost::apply_visitor(vis, m_values[m_attrName]);
980 OCRepresentation::iterator OCRepresentation::begin()
982 return OCRepresentation::iterator(m_values.begin(), m_values);
985 OCRepresentation::const_iterator OCRepresentation::begin() const
987 return OCRepresentation::const_iterator(m_values.begin(), m_values);
990 OCRepresentation::const_iterator OCRepresentation::cbegin() const
992 return OCRepresentation::const_iterator(m_values.cbegin(), m_values);
995 OCRepresentation::iterator OCRepresentation::end()
997 return OCRepresentation::iterator(m_values.end(), m_values);
1000 OCRepresentation::const_iterator OCRepresentation::end() const
1002 return OCRepresentation::const_iterator(m_values.end(), m_values);
1005 OCRepresentation::const_iterator OCRepresentation::cend() const
1007 return OCRepresentation::const_iterator(m_values.cend(), m_values);
1010 size_t OCRepresentation::size() const
1012 return m_values.size();
1015 bool OCRepresentation::empty() const
1017 return m_values.empty();
1020 bool OCRepresentation::iterator::operator==(const OCRepresentation::iterator& rhs) const
1022 return m_iterator == rhs.m_iterator;
1025 bool OCRepresentation::iterator::operator!=(const OCRepresentation::iterator& rhs) const
1027 return m_iterator != rhs.m_iterator;
1030 bool OCRepresentation::const_iterator::operator==(
1031 const OCRepresentation::const_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 OCRepresentation::iterator::reference OCRepresentation::iterator::operator*()
1047 OCRepresentation::const_iterator::const_reference
1048 OCRepresentation::const_iterator::operator*() const
1053 OCRepresentation::iterator::pointer OCRepresentation::iterator::operator->()
1058 OCRepresentation::const_iterator::const_pointer
1059 OCRepresentation::const_iterator::operator->() const
1064 OCRepresentation::iterator& OCRepresentation::iterator::operator++()
1067 if (m_iterator != m_item.m_values.end())
1069 m_item.m_attrName = m_iterator->first;
1073 m_item.m_attrName = "";
1078 OCRepresentation::const_iterator& OCRepresentation::const_iterator::operator++()
1081 if (m_iterator != m_item.m_values.end())
1083 m_item.m_attrName = m_iterator->first;
1087 m_item.m_attrName = "";
1092 OCRepresentation::iterator OCRepresentation::iterator::operator++(int)
1094 OCRepresentation::iterator itr(*this);
1099 OCRepresentation::const_iterator OCRepresentation::const_iterator::operator++(int)
1101 OCRepresentation::const_iterator itr(*this);
1106 struct to_string_visitor : boost::static_visitor<>
1109 template <typename T>
1110 void operator()(T const& item)
1112 str = boost::lexical_cast<std::string>(item);
1115 template <typename T>
1116 void operator()(std::vector<T> const& item)
1118 to_string_visitor vis;
1119 std::ostringstream stream;
1122 for(const auto& i : item)
1125 stream << vis.str << " ";
1133 void to_string_visitor::operator()(bool const& item)
1135 str = item ? "true" : "false";
1139 void to_string_visitor::operator()(std::string const& item)
1145 void to_string_visitor::operator()(NullType const& /*item*/)
1151 void to_string_visitor::operator()(std::vector<uint8_t> const &item)
1153 std::ostringstream stream;
1154 for (size_t i = 0; i < item.size(); i++ )
1156 stream << "\\x" << std::hex << (int) item[i];
1162 void to_string_visitor::operator()(OCByteString const &item)
1164 std::vector<uint8_t> v(item.bytes, item.bytes + item.len);
1169 void to_string_visitor::operator()(OCRepresentation const& /*item*/)
1171 str = "OC::OCRepresentation";
1174 std::string OCRepresentation::getValueToString(const std::string& key) const
1176 auto x = m_values.find(key);
1177 if (x != m_values.end())
1179 to_string_visitor vis;
1180 boost::apply_visitor(vis, x->second);
1181 return std::move(vis.str);
1187 std::string OCRepresentation::AttributeItem::getValueToString() const
1189 to_string_visitor vis;
1190 boost::apply_visitor(vis, m_values[m_attrName]);
1191 return std::move(vis.str);
1194 std::ostream& operator<<(std::ostream& os, const OCRepresentation::AttributeItem& ai)
1196 os << ai.getValueToString();