X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fsrc%2FOCRepresentation.cpp;h=3d42719c187b4171f3ec48712eaabe1a103ed1b0;hb=7f00f942c39b7bc27c7eeecf213a239c3fe4173c;hp=01969fcbbebfb667e083cd8d9c6a1a034fb22a32;hpb=3b9ded3a8b47384320cb06f5d8d905d54bd96bd6;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/src/OCRepresentation.cpp b/resource/src/OCRepresentation.cpp index 01969fc..3d42719 100644 --- a/resource/src/OCRepresentation.cpp +++ b/resource/src/OCRepresentation.cpp @@ -30,104 +30,41 @@ #include #include +#include #include "ocpayload.h" #include "ocrandom.h" #include "oic_malloc.h" #include "oic_string.h" +#include "ocstack.h" namespace OC { + static const char COAP[] = "coap://"; + static const char COAPS[] = "coaps://"; + static const char COAP_TCP[] = "coap+tcp://"; void MessageContainer::setPayload(const OCPayload* rep) { + if (rep == nullptr) + { + return; + } + switch(rep->type) { case PAYLOAD_TYPE_REPRESENTATION: setPayload(reinterpret_cast(rep)); break; - case PAYLOAD_TYPE_DEVICE: - setPayload(reinterpret_cast(rep)); - break; - case PAYLOAD_TYPE_PLATFORM: - setPayload(reinterpret_cast(rep)); - break; default: throw OC::OCException("Invalid Payload type in setPayload"); break; } } - void MessageContainer::setPayload(const OCDevicePayload* payload) - { - OCRepresentation rep; - rep.setUri(payload->uri); - char uuidString[UUID_STRING_SIZE]; - if(payload->sid && RAND_UUID_OK == OCConvertUuidToString(payload->sid, uuidString)) - { - rep[OC_RSRVD_DEVICE_ID] = std::string(uuidString); - } - else - { - rep[OC_RSRVD_DEVICE_ID] = std::string(); - } - rep[OC_RSRVD_DEVICE_NAME] = payload->deviceName ? - std::string(payload->deviceName) : - std::string(); - rep[OC_RSRVD_SPEC_VERSION] = payload->specVersion ? - std::string(payload->specVersion) : - std::string(); - rep[OC_RSRVD_DATA_MODEL_VERSION] = payload->dataModelVersion ? - std::string(payload->dataModelVersion) : - std::string(); - m_reps.push_back(std::move(rep)); - } - - void MessageContainer::setPayload(const OCPlatformPayload* payload) - { - OCRepresentation rep; - rep.setUri(payload->uri); - - rep[OC_RSRVD_PLATFORM_ID] = payload->info.platformID ? - std::string(payload->info.platformID) : - std::string(); - rep[OC_RSRVD_MFG_NAME] = payload->info.manufacturerName ? - std::string(payload->info.manufacturerName) : - std::string(); - rep[OC_RSRVD_MFG_URL] = payload->info.manufacturerUrl ? - std::string(payload->info.manufacturerUrl) : - std::string(); - rep[OC_RSRVD_MODEL_NUM] = payload->info.modelNumber ? - std::string(payload->info.modelNumber) : - std::string(); - rep[OC_RSRVD_MFG_DATE] = payload->info.dateOfManufacture ? - std::string(payload->info.dateOfManufacture) : - std::string(); - rep[OC_RSRVD_PLATFORM_VERSION] = payload->info.platformVersion ? - std::string(payload->info.platformVersion) : - std::string(); - rep[OC_RSRVD_OS_VERSION] = payload->info.operatingSystemVersion ? - std::string(payload->info.operatingSystemVersion) : - std::string(); - rep[OC_RSRVD_HARDWARE_VERSION] = payload->info.hardwareVersion ? - std::string(payload->info.hardwareVersion) : - std::string(); - rep[OC_RSRVD_FIRMWARE_VERSION] = payload->info.firmwareVersion ? - std::string(payload->info.firmwareVersion) : - std::string(); - rep[OC_RSRVD_SUPPORT_URL] = payload->info.supportUrl ? - std::string(payload->info.supportUrl) : - std::string(); - rep[OC_RSRVD_SYSTEM_TIME] = payload->info.systemTime ? - std::string(payload->info.systemTime) : - std::string(); - - m_reps.push_back(std::move(rep)); - } - void MessageContainer::setPayload(const OCRepPayload* payload) { const OCRepPayload* pl = payload; - while(pl) + while (pl) { OCRepresentation cur; cur.setPayload(pl); @@ -142,7 +79,7 @@ namespace OC OCRepPayload* root = nullptr; for(const auto& r : representations()) { - if(!root) + if (!root) { root = r.getPayload(); } @@ -181,6 +118,8 @@ namespace OC { root_size_calc(); dimensions[0] = arr.size(); + dimensions[1] = 0; + dimensions[2] = 0; dimTotal = calcDimTotal(dimensions); array = (void*)OICMalloc(dimTotal * root_size); @@ -196,6 +135,8 @@ namespace OC { root_size_calc(); dimensions[0] = arr.size(); + dimensions[1] = 0; + dimensions[2] = 0; for(size_t i = 0; i < arr.size(); ++i) { dimensions[1] = std::max(dimensions[1], arr[i].size()); @@ -216,6 +157,8 @@ namespace OC { root_size_calc(); dimensions[0] = arr.size(); + dimensions[1] = 0; + dimensions[2] = 0; for(size_t i = 0; i < arr.size(); ++i) { dimensions[1] = std::max(dimensions[1], arr[i].size()); @@ -286,11 +229,25 @@ namespace OC ((int64_t*)array)[pos] = item; } +#if !(defined(_MSC_VER) || defined(__APPLE__)) template<> void get_payload_array::copy_to_array(std::_Bit_reference br, void* array, size_t pos) { ((bool*)array)[pos] = static_cast(br); } +#endif + + template<> + void get_payload_array::copy_to_array(std::string item, void* array, size_t pos) + { + ((char**)array)[pos] = OICStrdup(item.c_str()); + } + + template<> + void get_payload_array::copy_to_array(std::string& item, void* array, size_t pos) + { + ((char**)array)[pos] = OICStrdup(item.c_str()); + } template<> void get_payload_array::copy_to_array(const std::string& item, void* array, size_t pos) @@ -299,6 +256,24 @@ namespace OC } template<> + void get_payload_array::copy_to_array(OCByteString item, void *array, size_t pos) + { + ((OCByteString *)array)[pos] = item; + } + + template<> + void get_payload_array::copy_to_array(OCByteString &item, void *array, size_t pos) + { + ((OCByteString *)array)[pos] = item; + } + + template<> + void get_payload_array::copy_to_array(const OCByteString &item, void *array, size_t pos) + { + ((OCByteString *)array)[pos] = item; + } + + template<> void get_payload_array::copy_to_array(OC::OCRepresentation item, void* array, size_t pos) { ((OCRepPayload**)array)[pos] = item.getPayload(); @@ -333,6 +308,10 @@ namespace OC (char**)vis.array, vis.dimensions); break; + case AttributeType::OCByteString: + OCRepPayloadSetByteStringArrayAsOwner(payload, item.attrname().c_str(), + (OCByteString *)vis.array, vis.dimensions); + break; case AttributeType::OCRepresentation: OCRepPayloadSetPropObjectArrayAsOwner(payload, item.attrname().c_str(), (OCRepPayload**)vis.array, vis.dimensions); @@ -346,7 +325,7 @@ namespace OC OCRepPayload* OCRepresentation::getPayload() const { OCRepPayload* root = OCRepPayloadCreate(); - if(!root) + if (!root) { throw std::bad_alloc(); } @@ -384,6 +363,9 @@ namespace OC OCRepPayloadSetPropString(root, val.attrname().c_str(), static_cast(val).c_str()); break; + case AttributeType::OCByteString: + OCRepPayloadSetPropByteString(root, val.attrname().c_str(), val.getValue()); + break; case AttributeType::OCRepresentation: OCRepPayloadSetPropObjectAsOwner(root, val.attrname().c_str(), static_cast(val).getPayload()); @@ -391,6 +373,11 @@ namespace OC case AttributeType::Vector: getPayloadArray(root, val); break; + case AttributeType::Binary: + OCRepPayloadSetPropByteString(root, val.attrname().c_str(), + OCByteString{const_cast(val.getValue>().data()), + val.getValue>().size()}); + break; default: throw std::logic_error(std::string("Getpayload: Not Implemented") + std::to_string((int)val.type())); @@ -398,23 +385,16 @@ namespace OC } } - OCRepPayload* cur = root; - for(auto& child : this->getChildren()) - { - cur->next = child.getPayload(); - cur = cur->next; - } - return root; } size_t calcArrayDepth(const size_t dimensions[MAX_REP_ARRAY_DEPTH]) { - if(dimensions[0] == 0) + if (dimensions[0] == 0) { throw std::logic_error("invalid calcArrayDepth"); } - else if(dimensions[1] == 0) + else if (dimensions[1] == 0) { return 1; } @@ -452,21 +432,44 @@ namespace OC std::string OCRepresentation::payload_array_helper_copy( size_t index, const OCRepPayloadValue* pl) { - return std::string(pl->arr.strArray[index]); + if (pl->arr.strArray[index]) + { + return std::string(pl->arr.strArray[index]); + } + else + { + return std::string{}; + } + } + + template<> + OCByteString OCRepresentation::payload_array_helper_copy( + size_t index, const OCRepPayloadValue *pl) + { + OCByteString result {NULL, 0}; + if (pl->arr.ocByteStrArray[index].len) + { + result = (pl->arr.ocByteStrArray[index]); + } + return result; } + template<> OCRepresentation OCRepresentation::payload_array_helper_copy( size_t index, const OCRepPayloadValue* pl) { OCRepresentation r; - r.setPayload(pl->arr.objArray[index]); + if (pl->arr.objArray[index]) + { + r.setPayload(pl->arr.objArray[index]); + } return r; } template void OCRepresentation::payload_array_helper(const OCRepPayloadValue* pl, size_t depth) { - if(depth == 1) + if (depth == 1) { std::vector val(pl->arr.dimensions[0]); @@ -481,7 +484,7 @@ namespace OC std::vector> val(pl->arr.dimensions[0]); for(size_t i = 0; i < pl->arr.dimensions[0]; ++i) { - val[i].reserve(pl->arr.dimensions[1]); + val[i].resize(pl->arr.dimensions[1]); for(size_t j = 0; j < pl->arr.dimensions[1]; ++j) { val[i][j] = payload_array_helper_copy( @@ -492,13 +495,13 @@ namespace OC } else if (depth == 3) { - std::vector>> val; + std::vector>> val(pl->arr.dimensions[0]); for(size_t i = 0; i < pl->arr.dimensions[0]; ++i) { - val[i].reserve(pl->arr.dimensions[1]); + val[i].resize(pl->arr.dimensions[1]); for(size_t j = 0; j < pl->arr.dimensions[1]; ++j) { - val[i][j].reserve(pl->arr.dimensions[2]); + val[i][j].resize(pl->arr.dimensions[2]); for(size_t k = 0; k < pl->arr.dimensions[2]; ++k) { val[i][j][k] = payload_array_helper_copy( @@ -534,6 +537,9 @@ namespace OC case OCREP_PROP_STRING: payload_array_helper(pl, calcArrayDepth(pl->arr.dimensions)); break; + case OCREP_PROP_BYTE_STRING: + payload_array_helper(pl, calcArrayDepth(pl->arr.dimensions)); + break; case OCREP_PROP_OBJECT: payload_array_helper(pl, calcArrayDepth(pl->arr.dimensions)); break; @@ -592,6 +598,12 @@ namespace OC case OCREP_PROP_ARRAY: setPayloadArray(val); break; + case OCREP_PROP_BYTE_STRING: + setValue(val->name, + std::vector + (val->ocByteStr.bytes, val->ocByteStr.bytes + val->ocByteStr.len) + ); + break; default: throw std::logic_error(std::string("Not Implemented!") + std::to_string((int)val->type)); @@ -620,6 +632,51 @@ namespace OC { m_children = children; } + + void OCRepresentation::setDevAddr(const OCDevAddr& devAddr) + { + std::ostringstream ss; + if (devAddr.flags & OC_SECURE) + { + ss << COAPS; + } + else if (devAddr.adapter & OC_ADAPTER_TCP) + { + ss << COAP_TCP; + } + else + { + ss << COAP; + } + if (devAddr.flags & OC_IP_USE_V6) + { + char addressEncoded[128] = {0}; + + OCStackResult result = OCEncodeAddressForRFC6874(addressEncoded, + sizeof(addressEncoded), + devAddr.addr); + if (OC_STACK_OK != result) + { + throw OC::OCException("Invalid address in setDevAddr"); + } + ss << '[' << addressEncoded << ']'; + } + else + { + ss << devAddr.addr; + } + if (devAddr.port) + { + ss << ':' << devAddr.port; + } + m_host = ss.str(); + } + + const std::string OCRepresentation::getHost() const + { + return m_host; + } + void OCRepresentation::setUri(const char* uri) { m_uri = uri ? uri : ""; @@ -665,6 +722,16 @@ namespace OC m_interfaces = resourceInterfaces; } + const std::vector& OCRepresentation::getDataModelVersions() const + { + return m_dataModelVersions; + } + + void OCRepresentation::addDataModelVersion(const std::string& str) + { + m_dataModelVersions.push_back(str); + } + bool OCRepresentation::hasAttribute(const std::string& str) const { return m_values.find(str) != m_values.end(); @@ -678,18 +745,19 @@ namespace OC // child of a default or link item. // Our values array is only printed in the if we are the child of a Batch resource, // the parent in a 'default' situation, or not in a child/parent relationship. - if(!m_uri.empty()) + if (!m_uri.empty()) { return false; } else if ((m_interfaceType == InterfaceType::None || m_interfaceType==InterfaceType::DefaultChild || m_interfaceType==InterfaceType::LinkChild) - && (m_resourceTypes.size()>0 || m_interfaces.size()>0)) + && (m_resourceTypes.size()>0 || m_interfaces.size()>0 + || m_dataModelVersions.size()>0)) { return false; } - else if((m_interfaceType == InterfaceType::None + else if ((m_interfaceType == InterfaceType::None || m_interfaceType == InterfaceType::BatchChild || m_interfaceType == InterfaceType::DefaultParent) && m_values.size()>0) @@ -697,7 +765,7 @@ namespace OC return false; } - if(m_children.size() > 0) + if (m_children.size() > 0) { return false; } @@ -724,7 +792,7 @@ namespace OC { auto x = m_values.find(str); - if(m_values.end() != x) + if (m_values.end() != x) { return x->second.which() == AttributeValueNullIndex; } @@ -756,12 +824,17 @@ namespace OC case AttributeType::String: os << "String"; break; + case AttributeType::OCByteString: + os << "OCByteString"; + break; case AttributeType::OCRepresentation: os << "OCRepresentation"; break; case AttributeType::Vector: os << "Vector"; break; + case AttributeType::Binary: + os<< "Binary"; } return os; } @@ -799,27 +872,45 @@ namespace OC // contains the inner most vector-type typedef T base_type; // contains the AttributeType for this item - constexpr static AttributeType enum_type = + BOOST_STATIC_CONSTEXPR AttributeType enum_type = AttributeTypeConvert::type; // contains the AttributeType for this base-type - constexpr static AttributeType enum_base_type = + BOOST_STATIC_CONSTEXPR AttributeType enum_base_type = AttributeTypeConvert::type; // depth of the vector - constexpr static size_t depth = 0; + BOOST_STATIC_CONSTEXPR size_t depth = 0; }; template - struct type_info::value>::type> + struct type_info< + T, + typename std::enable_if< + is_vector::value && + !std::is_same::value + >::type + > { typedef T type; typedef typename type_info::base_type base_type; - constexpr static AttributeType enum_type = AttributeType::Vector; - constexpr static AttributeType enum_base_type = + BOOST_STATIC_CONSTEXPR AttributeType enum_type = AttributeType::Vector; + BOOST_STATIC_CONSTEXPR AttributeType enum_base_type = type_info::enum_base_type; - constexpr static size_t depth = 1 + + BOOST_STATIC_CONSTEXPR size_t depth = 1 + type_info::depth; }; + // special case for binary data, which is a std::vector + template<> + struct type_info, void> + { + typedef std::vector type; + typedef std::vector base_type; + BOOST_STATIC_CONSTEXPR AttributeType enum_type = AttributeType::Binary; + BOOST_STATIC_CONSTEXPR AttributeType enum_base_type = AttributeType::Binary; + BOOST_STATIC_CONSTEXPR size_t depth = 0; + }; + + struct type_introspection_visitor : boost::static_visitor<> { AttributeType type; @@ -946,7 +1037,7 @@ namespace OC OCRepresentation::iterator& OCRepresentation::iterator::operator++() { m_iterator++; - if(m_iterator != m_item.m_values.end()) + if (m_iterator != m_item.m_values.end()) { m_item.m_attrName = m_iterator->first; } @@ -960,7 +1051,7 @@ namespace OC OCRepresentation::const_iterator& OCRepresentation::const_iterator::operator++() { m_iterator++; - if(m_iterator != m_item.m_values.end()) + if (m_iterator != m_item.m_values.end()) { m_item.m_attrName = m_iterator->first; } @@ -1029,6 +1120,24 @@ namespace OC str = "(null)"; } + template <> + void to_string_visitor::operator()(std::vector const &item) + { + std::ostringstream stream; + for (size_t i = 0; i < item.size(); i++ ) + { + stream << "\\x" << std::hex << (int) item[i]; + } + str = stream.str(); + } + + template<> + void to_string_visitor::operator()(OCByteString const &item) + { + std::vector v(item.bytes, item.bytes + item.len); + operator()(v); + } + template<> void to_string_visitor::operator()(OCRepresentation const& /*item*/) { @@ -1038,7 +1147,7 @@ namespace OC std::string OCRepresentation::getValueToString(const std::string& key) const { auto x = m_values.find(key); - if(x != m_values.end()) + if (x != m_values.end()) { to_string_visitor vis; boost::apply_visitor(vis, x->second); @@ -1061,4 +1170,3 @@ namespace OC return os; } } -