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
00161
00162
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