OpaqueTypelibMarshaller.hpp
Go to the documentation of this file.
00001 #ifndef OPAQUE_TYPELIB_MARRSHALLER_HPP
00002 #define OPAQUE_TYPELIB_MARRSHALLER_HPP
00003 
00004 #include <rtt/typelib/TypelibMarshallerBase.hpp>
00005 #include <rtt/typelib/TypelibMarshallerHandle.hpp>
00006 #include <rtt/internal/DataSources.hpp>
00007 
00008 namespace orogen_transports {
00009 
00010 template<typename TypelibType, typename OpaqueType>
00011 struct OpaqueTypelibMarshallerBase : public orogen_transports::TypelibMarshallerBase
00012 {
00013     typedef orogen_transports::TypelibMarshallerBase::Handle MarshallingHandle;
00014     typedef OpaqueType  opaque_t;
00015     typedef TypelibType typelib_t;
00016 
00017     OpaqueTypelibMarshallerBase(std::string const& typelib_name, std::string const& opaque_name, Typelib::Registry const& registry)
00018         : orogen_transports::TypelibMarshallerBase(false, typelib_name, opaque_name, registry) { }
00019 
00020     RTT::base::DataSourceBase::shared_ptr getDataSource(Handle* handle)
00021     {
00022         ensureOrocosSamplePresent(handle);
00023         return new RTT::internal::ReferenceDataSource< opaque_t >(*reinterpret_cast< opaque_t* >(handle->orocos_sample));
00024     }
00025 
00026     void deleteOrocosSample(MarshallingHandle* data)
00027     { delete reinterpret_cast<opaque_t*>(data->orocos_sample); }
00028     void deleteTypelibSample(MarshallingHandle* data)
00029     { delete reinterpret_cast<typelib_t*>(data->typelib_sample); }
00030 
00031     uint8_t* releaseOrocosSample(Handle* handle)
00032     {
00033         if (!handle->orocos_sample)
00034             return 0;
00035 
00036         if (handle->owns_orocos)
00037         {
00038             return reinterpret_cast<uint8_t*>(new opaque_t(*reinterpret_cast<opaque_t*>(handle->orocos_sample)));
00039         }
00040         else
00041         {
00042             handle->owns_orocos = false;
00043             uint8_t* result = handle->orocos_sample;
00044             handle->orocos_sample = 0;
00045             return result;
00046         }
00047     }
00048 
00049     void ensureOrocosSamplePresent(MarshallingHandle* handle)
00050     {
00051         if (!handle->orocos_sample)
00052         {
00053             handle->orocos_sample = reinterpret_cast<uint8_t*>(new opaque_t);
00054             handle->owns_orocos  = true;
00055         }
00056     }
00057 
00058     void ensureTypelibSamplePresent(MarshallingHandle* handle)
00059     {
00060         if (!handle->typelib_sample)
00061         {
00062             handle->typelib_sample = reinterpret_cast<uint8_t*>(new typelib_t);
00063             handle->owns_typelib  = true;
00064         }
00065     }
00066 
00067     void setOrocosSample(MarshallingHandle* handle, void* data, bool refresh_typelib = true)
00068     {
00069         if (handle->owns_orocos)
00070             deleteOrocosSample(handle);
00071         handle->orocos_sample = reinterpret_cast<uint8_t*>(data);
00072         handle->owns_orocos = false;
00073 
00074         if (refresh_typelib)
00075             refreshTypelibSample(handle);
00076     }
00077 
00078     bool readDataSource(RTT::base::DataSourceBase& source_base, MarshallingHandle* handle)
00079     {
00080         RTT::internal::DataSource<opaque_t>& source = dynamic_cast<RTT::internal::DataSource<opaque_t>&>(source_base);
00081         if (source.evaluate())
00082         {
00083             ensureOrocosSamplePresent(handle);
00084             opaque_t& opaque_sample =
00085                 *reinterpret_cast<opaque_t*>(handle->orocos_sample);
00086             opaque_sample = source.value();
00087             refreshTypelibSample(handle);
00088             return true;
00089         }
00090         return false;
00091     }
00092     void writeDataSource(RTT::base::DataSourceBase& source, MarshallingHandle const* handle)
00093     {
00094         opaque_t const& data = *reinterpret_cast<opaque_t const*>(handle->orocos_sample);
00095         dynamic_cast<RTT::internal::AssignableDataSource<opaque_t>&>(source).set(data);
00096     }
00097 
00098     void unmarshal(void const* buffer, int size, Handle* handle)
00099     {
00100         ensureTypelibSamplePresent(handle);
00101         TypelibMarshallerBase::unmarshal(buffer, size, handle);
00102         refreshOrocosSample(handle);
00103     }
00104 
00105     void unmarshal(std::vector<uint8_t>& buffer, Handle* handle)
00106     {
00107         ensureTypelibSamplePresent(handle);
00108         TypelibMarshallerBase::unmarshal(buffer, handle);
00109         refreshOrocosSample(handle);
00110     }
00111 };
00112 
00113 template<typename TypelibType, typename OpaqueType, int needs_copy>
00114 class OpaqueTypelibMarshaller;
00115 
00116 template<typename TypelibType, typename OpaqueType>
00117 struct OpaqueTypelibMarshaller<TypelibType, OpaqueType, 0> : public OpaqueTypelibMarshallerBase<TypelibType, OpaqueType>
00118 {
00119     typedef orogen_transports::TypelibMarshallerBase::Handle MarshallingHandle;
00120     typedef OpaqueType  opaque_t;
00121     typedef TypelibType typelib_t;
00122 
00123     OpaqueTypelibMarshaller(std::string const& typelib_name, std::string const& opaque_name, Typelib::Registry const& registry)
00124         : OpaqueTypelibMarshallerBase<TypelibType, OpaqueType>(typelib_name, opaque_name, registry) {}
00125 
00126     MarshallingHandle* createSample()
00127     {
00128         return new MarshallingHandle(this, (typelib_t*)0, new opaque_t);
00129     }
00130 
00131     void refreshTypelibSample(MarshallingHandle* handle)
00132     {
00133         this->ensureOrocosSamplePresent(handle);
00134         opaque_t& opaque_sample =
00135             *reinterpret_cast<opaque_t*>(handle->orocos_sample);
00136 
00137         if (handle->typelib_sample && handle->owns_typelib)
00138             this->deleteTypelibSample(handle);
00139 
00140         handle->typelib_sample = const_cast<uint8_t*>(
00141                 reinterpret_cast<uint8_t const*>(
00142                     &orogen_typekits::toIntermediate(opaque_sample) ));
00143         handle->owns_typelib = false;
00144     }
00145 
00146     void refreshOrocosSample(MarshallingHandle* handle)
00147     { 
00148         this->ensureOrocosSamplePresent(handle);
00149 
00150         opaque_t& opaque_sample =
00151             *reinterpret_cast<opaque_t*>(handle->orocos_sample);
00152         typelib_t& typelib_sample =
00153             *reinterpret_cast<typelib_t*>(handle->typelib_sample);
00154         handle->owns_typelib =
00155             !orogen_typekits::fromIntermediate(opaque_sample, &typelib_sample);
00156     }
00157 
00158     void setTypelibSample(MarshallingHandle* handle, uint8_t* typelib_data, bool refresh_orocos = true)
00159     {
00160         // The orocos sample might take ownership of the typelib sample
00161         // To avoid too complicated ownership logic for the users of this class,
00162         // we do a copy first.
00163         if (!handle->typelib_sample || !handle->owns_typelib)
00164         {
00165             handle->typelib_sample = reinterpret_cast<uint8_t*>(new typelib_t);
00166             handle->owns_typelib = true;
00167         }
00168         typelib_t& new_value =
00169             *reinterpret_cast<typelib_t*>(typelib_data);
00170         typelib_t& intermediate_sample =
00171             *reinterpret_cast<typelib_t*>(handle->typelib_sample);
00172         intermediate_sample = new_value;
00173 
00174         if (refresh_orocos)
00175             refreshOrocosSample(handle);
00176     }
00177 };
00178 
00179 template<typename TypelibType, typename OpaqueType>
00180 struct OpaqueTypelibMarshaller<TypelibType, OpaqueType, 1> : public OpaqueTypelibMarshallerBase<TypelibType, OpaqueType>
00181 {
00182     typedef orogen_transports::TypelibMarshallerBase::Handle MarshallingHandle;
00183     typedef OpaqueType  opaque_t;
00184     typedef TypelibType typelib_t;
00185 
00186     OpaqueTypelibMarshaller(std::string const& typelib_name, std::string const& opaque_name, Typelib::Registry const& registry)
00187         : OpaqueTypelibMarshallerBase<TypelibType, OpaqueType>(typelib_name, opaque_name, registry) {}
00188 
00189     MarshallingHandle* createSample()
00190     {
00191         return new MarshallingHandle(this, new typelib_t, new opaque_t);
00192     }
00193 
00194     void refreshTypelibSample(MarshallingHandle* handle)
00195     {
00196         this->ensureOrocosSamplePresent(handle);
00197         opaque_t& opaque_sample =
00198             *reinterpret_cast<opaque_t*>(handle->orocos_sample);
00199 
00200         this->ensureTypelibSamplePresent(handle);
00201         typelib_t& intermediate_sample =
00202             *reinterpret_cast<typelib_t*>(handle->typelib_sample);
00203         orogen_typekits::toIntermediate(intermediate_sample, opaque_sample);
00204     }
00205 
00206     void refreshOrocosSample(MarshallingHandle* handle)
00207     { 
00208         this->ensureOrocosSamplePresent(handle);
00209 
00210         opaque_t& opaque_sample =
00211             *reinterpret_cast<opaque_t*>(handle->orocos_sample);
00212         typelib_t& typelib_sample =
00213             *reinterpret_cast<typelib_t*>(handle->typelib_sample);
00214         orogen_typekits::fromIntermediate(opaque_sample, typelib_sample);
00215     }
00216 
00217     void setTypelibSample(MarshallingHandle* handle, uint8_t* typelib_data, bool refresh_orocos = true)
00218     {
00219         if (handle->owns_typelib)
00220             this->deleteTypelibSample(handle);
00221         handle->typelib_sample = typelib_data;
00222         handle->owns_typelib   = false;
00223 
00224         if (refresh_orocos)
00225             refreshOrocosSample(handle);
00226     }
00227 };
00228 
00229 }
00230 
00231 #endif
00232 


rtt_typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Thu Jan 2 2014 11:38:53