//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#ifndef COMMON_INTERNAL_RESOURCEATTRIBUTESCONVERTER_H
-#define COMMON_INTERNAL_RESOURCEATTRIBUTESCONVERTER_H
+#ifndef COMMON_RESOURCEATTRIBUTESCONVERTER_H
+#define COMMON_RESOURCEATTRIBUTESCONVERTER_H
-#include <ResourceAttributes.h>
+#include <RCSResourceAttributes.h>
#include <OCRepresentation.h>
{
namespace Service
{
+ namespace Detail
+ {
+ template< int >
+ struct Int2Type {};
+
+ template < typename T >
+ struct TypeDef
+ {
+ typedef T type;
+ };
+
+ template< OC::AttributeType TYPE >
+ struct OCBaseType;
+
+ template< >
+ struct OCBaseType< OC::AttributeType::Integer > : TypeDef< int >{ };
+
+ template< >
+ struct OCBaseType< OC::AttributeType::Double > : TypeDef< double > { };
+
+ template< >
+ struct OCBaseType< OC::AttributeType::Boolean > : TypeDef< bool > { };
+
+ template< >
+ struct OCBaseType< OC::AttributeType::String > : TypeDef< std::string > { };
+
+ template< >
+ struct OCBaseType< OC::AttributeType::Binary > : TypeDef< RCSByteString::DataType > { };
+
+ template< >
+ struct OCBaseType< OC::AttributeType::OCByteString > : TypeDef< OCByteString > { };
+
+ template< >
+ struct OCBaseType< OC::AttributeType::OCRepresentation >
+ : TypeDef< OC::OCRepresentation >
+ {};
+
+ template< int DEPTH, typename BASE_TYPE >
+ struct SeqType
+ {
+ typedef std::vector< typename SeqType< DEPTH - 1, BASE_TYPE >::type > type;
+ };
+
+ template< typename BASE_TYPE >
+ struct SeqType< 0, BASE_TYPE >
+ {
+ typedef BASE_TYPE type;
+ };
+
+ template< int DEPTH, OC::AttributeType BASE_TYPE >
+ struct OCItemType
+ {
+ typedef typename SeqType< DEPTH,
+ typename OCBaseType< BASE_TYPE >::type >::type type;
+ };
+
+ template< typename T >
+ struct TypeInfo
+ {
+ typedef T type;
+ typedef T base_type;
+ constexpr static size_t depth = 0;
+ };
+
+ template< typename T >
+ struct TypeInfo< std::vector< T > >
+ {
+ typedef T type;
+ typedef typename TypeInfo< T >::base_type base_type;
+ constexpr static size_t depth = 1 + TypeInfo< T >::depth;
+ };
+ }
class ResourceAttributesConverter
{
class ResourceAttributesBuilder
{
- public:
- ResourceAttributesBuilder() = default;
-
- void insertItemTo(const OC::OCRepresentation::AttributeItem& item)
+ private:
+ template < int DEPTH >
+ void insertItem(Detail::Int2Type< DEPTH >,
+ const OC::OCRepresentation::AttributeItem& item)
{
- switch (item.type())
- {
+ switch (item.base_type()) {
case OC::AttributeType::Null:
return putValue(item.attrname(), nullptr);
case OC::AttributeType::Integer:
- return putValue(item.attrname(), item.getValue< int >());
+ return insertItem< DEPTH, OC::AttributeType::Integer >(item);
case OC::AttributeType::Double:
- return putValue(item.attrname(), item.getValue< double >());
+ return insertItem< DEPTH, OC::AttributeType::Double >(item);
case OC::AttributeType::Boolean:
- return putValue(item.attrname(), item.getValue< bool >());
+ return insertItem< DEPTH, OC::AttributeType::Boolean >(item);
case OC::AttributeType::String:
- return putValue(item.attrname(), item.getValue< std::string >());
+ return insertItem< DEPTH, OC::AttributeType::String >(item);
+
+ case OC::AttributeType::Binary:
+ // OCRep support only 0-depth for binary type.
+ // If RI changed, this line should be changed to DEPTH.
+ return insertOcBinary< OC::AttributeType::Binary >
+ (Detail::Int2Type< 0 >{ }, item);
+
+ case OC::AttributeType::OCByteString:
+ return insertOcBinary< OC::AttributeType::OCByteString >
+ (Detail::Int2Type< DEPTH >{ }, item);
case OC::AttributeType::OCRepresentation:
- return putValue(item.attrname(),
- ResourceAttributesConverter::fromOCRepresentation(
- item.getValue< OC::OCRepresentation >()));
+ return insertOcRep(Detail::Int2Type< DEPTH >{ }, item);
- case OC::AttributeType::Vector:
- // ResourceAttributes doesn't support vector yet!
- return;
+ default:
+ assert("There must be no another base type!");
}
}
- ResourceAttributes&& extract()
+ template< int DEPTH, OC::AttributeType BASE_TYPE >
+ void insertItem(const OC::OCRepresentation::AttributeItem& item)
{
- return std::move(m_target);
+ typedef typename Detail::OCItemType< DEPTH, BASE_TYPE >::type ItemType;
+ putValue(item.attrname(), item.getValue< ItemType >());
}
- private:
- template< typename T >
- typename std::enable_if<ResourceAttributes::is_supported_type< T >::value >::type
- putValue(const std::string& key, T && value)
+ RCSResourceAttributes insertOcRep(Detail::Int2Type< 0 >,
+ const OC::OCRepresentation& ocRep)
{
- m_target[key] = std::forward< T >(value);
+ return ResourceAttributesConverter::fromOCRepresentation(ocRep);
+ }
+
+ template< int DEPTH, typename OCREPS,
+ typename ATTRS = typename Detail::SeqType< DEPTH, RCSResourceAttributes >::type >
+ ATTRS insertOcRep(Detail::Int2Type< DEPTH >, const OCREPS& ocRepVec)
+ {
+ ATTRS result;
+
+ for (const auto& nested : ocRepVec)
+ {
+ result.push_back(insertOcRep(Detail::Int2Type< DEPTH - 1 >{ }, nested));
+ }
+
+ return result;
}
+ template< int DEPTH >
+ void insertOcRep(Detail::Int2Type< DEPTH >,
+ const OC::OCRepresentation::AttributeItem& item)
+ {
+ typedef typename Detail::OCItemType< DEPTH,
+ OC::AttributeType::OCRepresentation >::type ItemType;
+
+ putValue(item.attrname(),
+ insertOcRep(Detail::Int2Type< DEPTH >{ }, item.getValue< ItemType >()));
+ }
+
+ template< typename OCREP >
+ RCSByteString insertOcBinary(Detail::Int2Type< 0 >, const OCREP& ocBinary)
+ {
+ return RCSByteString(ocBinary);
+ }
+
+ template< int DEPTH, typename OCREPS,
+ typename ATTRS = typename Detail::SeqType< DEPTH, RCSByteString >::type >
+ ATTRS insertOcBinary(Detail::Int2Type< DEPTH >, const OCREPS& ocBinaryVec)
+ {
+ ATTRS result;
+
+ for (const auto& nested : ocBinaryVec)
+ {
+ result.push_back(insertOcBinary(Detail::Int2Type< DEPTH - 1 >{ }, nested));
+ }
+
+ return result;
+ }
+
+ template< OC::AttributeType BASE_TYPE, int DEPTH >
+ void insertOcBinary(Detail::Int2Type< DEPTH >,
+ const OC::OCRepresentation::AttributeItem& item)
+ {
+ typedef typename Detail::OCItemType< DEPTH, BASE_TYPE >::type ItemType;
+
+ putValue(item.attrname(),
+ insertOcBinary(Detail::Int2Type< DEPTH >{ },
+ item.getValue< ItemType >()));
+ }
+
+ public:
+ ResourceAttributesBuilder() = default;
+
+ void insertItem(const OC::OCRepresentation::AttributeItem& item)
+ {
+ switch (item.depth())
+ {
+ case 0:
+ return insertItem(Detail::Int2Type< 0 >{ }, item);
+ case 1:
+ return insertItem(Detail::Int2Type< 1 >{ }, item);
+ case 2:
+ return insertItem(Detail::Int2Type< 2 >{ }, item);
+ case 3:
+ return insertItem(Detail::Int2Type< 3 >{ }, item);
+
+ default:
+ assert("There must be no another depth!");
+ }
+ }
+
+ RCSResourceAttributes&& extract()
+ {
+ return std::move(m_target);
+ }
+
+ private:
template< typename T >
- typename std::enable_if<!ResourceAttributes::is_supported_type< T >::value >::type
- putValue(const std::string& key, T && value)
+ void putValue(const std::string& key, T&& value)
{
+ m_target[key] = std::forward< T >(value);
}
private:
- ResourceAttributes m_target;
+ RCSResourceAttributes m_target;
};
class OCRepresentationBuilder
public:
OCRepresentationBuilder() = default;
- template< typename T >
- void operator()(const std::string& key, const T& value)
+ template< typename T, typename B = typename Detail::TypeInfo< T >::base_type >
+ typename std::enable_if< (
+ !std::is_same< B, RCSResourceAttributes >::value &&
+ !std::is_same< B, RCSByteString >::value
+ )>::type
+ operator()(const std::string& key, const T& value)
{
m_target[key] = value;
}
+ template< typename T, typename I = Detail::TypeInfo< T > >
+ typename std::enable_if< std::is_same< typename I::base_type,
+ RCSResourceAttributes >::value >::type
+ operator()(const std::string& key, const T& value)
+ {
+ m_target[key] = convertAttributes(Detail::Int2Type< I::depth >{ }, value);
+ }
+
+ template< typename T, typename I = Detail::TypeInfo< T > >
+ typename std::enable_if< std::is_same< typename I::base_type,
+ RCSByteString >::value >::type
+ operator()(const std::string& key, const T& value)
+ {
+ m_target[key] = convertByteString(Detail::Int2Type< I::depth >{ }, value);
+ }
+
void operator()(const std::string& key, const std::nullptr_t&)
{
m_target.setNULL(key);
}
- void operator()(const std::string& key, const ResourceAttributes& value)
+ OC::OCRepresentation convertAttributes(Detail::Int2Type< 0 >,
+ const RCSResourceAttributes& attrs)
+ {
+ return ResourceAttributesConverter::toOCRepresentation(attrs);
+ }
+
+ template< int DEPTH, typename ATTRS, typename OCREPS = typename Detail::SeqType<
+ DEPTH, OC::OCRepresentation >::type >
+ OCREPS convertAttributes(Detail::Int2Type< DEPTH >, const ATTRS& attrs)
+ {
+ OCREPS result;
+
+ for (const auto& nested : attrs)
+ {
+ result.push_back(
+ convertAttributes(Detail::Int2Type< DEPTH - 1 >{ }, nested));
+ }
+
+ return result;
+ }
+
+ OCByteString convertByteString(Detail::Int2Type< 0 >,
+ const RCSByteString& byteString)
{
- m_target[key] = ResourceAttributesConverter::toOCRepresentation(value);
+ OCByteString blob;
+ blob.len = byteString.size();
+ blob.bytes = new uint8_t[blob.len];
+ for (size_t i = 0; i < blob.len; ++i)
+ {
+ blob.bytes[i] = byteString[i];
+ }
+
+ return blob;
+ }
+
+ template< int DEPTH, typename ATTRS, typename OCREPS = typename Detail::SeqType<
+ DEPTH, OCByteString >::type >
+ OCREPS convertByteString(Detail::Int2Type< DEPTH >, const ATTRS& byteStringVec)
+ {
+ OCREPS result;
+
+ for (const auto& nested : byteStringVec)
+ {
+ result.push_back(
+ convertByteString(Detail::Int2Type< DEPTH - 1 >{ }, nested));
+ }
+
+ return result;
}
OC::OCRepresentation&& extract()
};
public:
- static ResourceAttributes fromOCRepresentation(
+ static RCSResourceAttributes fromOCRepresentation(
const OC::OCRepresentation& ocRepresentation)
{
ResourceAttributesBuilder builder;
for (const auto& item : ocRepresentation)
{
- builder.insertItemTo(item);
+ builder.insertItem(item);
}
return builder.extract();
}
static OC::OCRepresentation toOCRepresentation(
- const ResourceAttributes& resourceAttributes)
+ const RCSResourceAttributes& resourceAttributes)
{
OCRepresentationBuilder builder;
}
}
-#endif // COMMON_INTERNAL_RESOURCEATTRIBUTESCONVERTER_H
+#endif // COMMON_RESOURCEATTRIBUTESCONVERTER_H