See More

#include "TypeWrapper.hpp" #include // /home/planthaber/dfki/workspace/terrain_exploration/workspace/gui/rock-display/src/configuration.cpp namespace orocos_cpp { TypeWrapper::TypeWrapper(Typelib::Value& value):value(value) { switch (value.getType().getCategory()) { case Typelib::Type::Category::Compound: addCompound(); break; case Typelib::Type::Category::Container: addContainer(); break; case Typelib::Type::Category::Array: addArray(); break; case Typelib::Type::Category::Numeric: category = Typelib::Type::Category::Numeric; break; default: std::cout << "category "<< value.getType().getCategory() << " of type " << value.getType().getName() << std::endl; break; } } void TypeWrapper::addCompound() { category = Typelib::Type::Category::Compound; // iterate fields const Typelib::Compound& compound = static_cast(value.getType()); uint8_t *data = static_cast(value.getData()); for (const auto& field : compound.getFields()) { Typelib::Value newvalue(data + field.getOffset(), field.getType()); // as the [] operator is overloaded, we need to call directly std::map<:string std::shared_ptr>>::operator[](field.getName()) = std::make_shared(newvalue); } } void TypeWrapper::addContainer() { category = Typelib::Type::Category::Container; const Typelib::Container& container = dynamic_cast(value.getType()); if (container.isRandomAccess()) { for (size_t i = 0; i < container.getElementCount(value.getData()); ++i) { Typelib::Value newvalue = container.getElement(value.getData(), i); // as the [] operator is overloaded, we need to call directly std::map<:string std::shared_ptr>>::operator[](std::to_string(i)) = std::make_shared(newvalue); } } else { // should be a /std/string //printf("%s:%i\n", __PRETTY_FUNCTION__, __LINE__); } } void TypeWrapper::addArray() { category = Typelib::Type::Category::Array; const Typelib::Array& array = dynamic_cast(value.getType()); const Typelib::Type &indirect(array.getIndirection()); for (size_t i = 0; i < array.getDimension(); ++i) { Typelib::Value newvalue(static_cast(value.getData()) + i * indirect.getSize(), indirect); // as the [] operator is overloaded, we need to call directly std::map<:string std::shared_ptr>>::operator[](std::to_string(i)) = std::make_shared(newvalue); } } std::string TypeWrapper::toString() { switch (value.getType().getCategory()) { //case Typelib::Type::Category::Compound: return compoundToString(); case Typelib::Type::Category::Numeric: return numericToString(); case Typelib::Type::Category::Container: return containerToString(); default: return ""; } } double TypeWrapper::toDouble() { if (value.getType().getCategory() != Typelib::Type::Category::Numeric) { throw std::runtime_error("Type is not numeric"); } if (value.getType().getCategory() == Typelib::Type::Category::Numeric) { const Typelib::Numeric& numeric = dynamic_cast(value.getType()); switch (numeric.getNumericCategory()) { // "/bool" is encoded as uint8_t, no need for extra treatment case Typelib::Numeric::Float: if (numeric.getSize() == sizeof(float)) { return *static_cast(value.getData()); } else { return *static_cast(value.getData()); } case Typelib::Numeric::SInt: switch (numeric.getSize()) { case sizeof(int8_t): return static_cast(*static_cast(value.getData())); case sizeof(int16_t): return *static_cast(value.getData()); case sizeof(int32_t): return *static_cast(value.getData()); case sizeof(int64_t): return *static_cast(value.getData()); default: std::cerr << "Error, got integer of unexpected size " << numeric.getSize() << std::endl; throw std::runtime_error("got integer of unexpected size"); } case Typelib::Numeric::UInt: { switch (numeric.getSize()) { case sizeof(uint8_t): return static_cast(*static_cast(value.getData())); case sizeof(uint16_t): return *static_cast(value.getData()); case sizeof(uint32_t): return *static_cast(value.getData()); case sizeof(uint64_t): return *static_cast(value.getData()); default: std::cout << "Error, got integer of unexpected size " << numeric.getSize() << std::endl; throw std::runtime_error("got integer of unexpected size"); } } case Typelib::Numeric::NumberOfValidCategories: default: throw std::runtime_error("Internal Error: Got invalid Category"); } } return 0; } std::string TypeWrapper::numericToString() { if (value.getType().getCategory() == Typelib::Type::Category::Numeric) { if (value.getType().getName() == "/bool") { return (*static_cast(value.getData())?"true":"false"); } return std::to_string(toDouble()); } return ""; } std::string TypeWrapper::containerToString() { const Typelib::Container& container = dynamic_cast(value.getType()); if (container.getName() == "/std/string") { return *static_cast(value.getData()); } // this is a real container, will be represented by other typewrappers return ""; } void TypeWrapper::printType(std::string ident) { std::cout << ident << this->value.getType().getName() << ": \t" << this->toString() << std::endl; ident = ident + " "; for (auto& entry : *this) { std::cout << ident << entry.first << "\t"; entry.second->printType(ident); } } } // namespace orocos_cpp