$search
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