00001 #ifndef PI_PROPERTIES_NETCDFTABLESERIALIZER
00002 #define PI_PROPERTIES_NETCDFTABLESERIALIZER
00003
00004 #include "rtt/Property.hpp"
00005 #include "rtt/PropertyIntrospection.hpp"
00006 #include <boost/lexical_cast.hpp>
00007
00008 #include <netcdf.h>
00009
00010 namespace RTT
00011 {
00012
00018 class NetcdfMarshaller
00019 : public Marshaller
00020 {
00021 int ncid;
00022 size_t index;
00023 int nameless_counter;
00024 std::string prefix;
00025
00026 public:
00031 NetcdfMarshaller(int ncid) :
00032 ncid ( ncid ) {index=0;}
00033
00034 virtual ~NetcdfMarshaller() {}
00035
00036 virtual void serialize(PropertyBase* v)
00037 {
00038 Property<PropertyBag>* bag = dynamic_cast< Property<PropertyBag>* >( v );
00039 if ( bag )
00040 this->serialize( *bag );
00041 else {
00042 Property<char>* Pc = dynamic_cast< Property<char>* >( v );
00043 if ( Pc )
00044 {
00045 store(Pc);
00046 return;
00047 }
00048 Property<short>* Ps = dynamic_cast< Property<short>* >( v );
00049 if ( Ps )
00050 {
00051 store(Ps);
00052 return;
00053 }
00054 Property<int>* Pi = dynamic_cast< Property<int>* >( v );
00055 if (Pi)
00056 {
00057 store(Pi);
00058 return;
00059 }
00060 Property<float>* Pf = dynamic_cast< Property<float>* >( v );
00061 if (Pf)
00062 {
00063 store(Pf);
00064 return;
00065 }
00066 Property<double>* Pd = dynamic_cast< Property<double>* >( v );
00067 if (Pd)
00068 {
00069 store(Pd);
00070 return;
00071 }
00072 Property<std::vector<double> >* Pv = dynamic_cast< Property<std::vector<double> >* >( v );
00073 if (Pv)
00074 {
00075 store(Pv);
00076 return;
00077 }
00078
00079 Property<PropertyBag> bag( v->getName(), "");
00080 v->getTypeInfo()->decomposeType( v->getDataSource(), bag.value() );
00081 this->serialize( bag );
00082 deleteProperties( bag.value() );
00083
00084 }
00085 }
00086
00087 virtual void serialize(const PropertyBag &v)
00088 {
00089 for (
00090 PropertyBag::const_iterator i = v.getProperties().begin();
00091 i != v.getProperties().end();
00092 i++ )
00093 {
00094 this->serialize( *i );
00095 }
00096 }
00097
00098 virtual void serialize(const Property<PropertyBag> &v)
00099 {
00100 std::string oldpref = prefix;
00101
00102
00103 if(prefix.empty())
00104 prefix = v.getName();
00105 else
00106 prefix += "." + v.getName();
00107
00108 serialize(v.get());
00109
00110 prefix = oldpref;
00111 nameless_counter = 0;
00112 }
00113
00117 void store(Property<char> *v)
00118 {
00119 int retval;
00120 int varid;
00121 signed char value = v->get();
00122 std::string sname = composeName(v->getName());
00123
00127 retval = nc_inq_varid(ncid, sname.c_str(), &varid);
00128 if (retval)
00129 log(Error) << "Could not get variable id of " << sname << ", error " << retval <<endlog();
00130
00134 retval = nc_put_var1_schar(ncid, varid, &index, &value);
00135 if(retval)
00136 log(Error) << "Could not write variable " << sname << ", error " << retval <<endlog();
00137 }
00138
00142 void store(Property<short> *v)
00143 {
00144
00145 int retval;
00146 int varid;
00147 short value = v->get();
00148 std::string sname = composeName(v->getName());
00149
00153 retval = nc_inq_varid(ncid, sname.c_str(), &varid);
00154 if (retval)
00155 log(Error) << "Could not get variable id of " << sname << ", error " << retval <<endlog();
00156
00160 retval = nc_put_var1_short(ncid, varid, &index, &value);
00161 if(retval)
00162 log(Error) << "Could not write variable " << sname << ", error " << retval <<endlog();
00163 }
00164
00168 void store(Property<int> *v)
00169 {
00170 int retval;
00171 int varid;
00172 int value = v->get();
00173 std::string sname = composeName(v->getName());
00174
00178 retval = nc_inq_varid(ncid, sname.c_str(), &varid);
00179 if (retval)
00180 log(Error) << "Could not get variable id of " << sname << ", error " << retval <<endlog();
00181
00185 retval = nc_put_var1_int(ncid, varid, &index, &value);
00186 if(retval)
00187 log(Error) << "Could not write variable " << sname << ", error " << retval <<endlog();
00188 }
00189
00193 void store(Property<float> *v)
00194 {
00195 int retval;
00196 int varid;
00197 float value = v->get();
00198 std::string sname = composeName(v->getName());
00199
00203 retval = nc_inq_varid(ncid, sname.c_str(), &varid);
00204 if (retval)
00205 log(Error) << "Could not get variable id of " << sname << ", error " << retval <<endlog();
00206
00210 retval = nc_put_var1_float(ncid, varid, &index, &value);
00211 if(retval)
00212 log(Error) << "Could not write variable " << sname << ", error " << retval <<endlog();
00213
00214 }
00215
00219 void store(Property<double> *v)
00220 {
00221 int retval;
00222 int varid;
00223 double value = v->get();
00224 std::string sname = composeName(v->getName());
00225
00229 retval = nc_inq_varid(ncid, sname.c_str(), &varid);
00230 if (retval)
00231 log(Error) << "Could not get variable id of " << sname << ", error " << retval <<endlog();
00232
00236 retval = nc_put_var1_double(ncid, varid, &index, &value);
00237 if(retval)
00238 log(Error) << "Could not write variable " << sname << ", error " << retval <<endlog();
00239 }
00240
00244 void store(Property<std::vector<double> > *v)
00245 {
00246 int retval;
00247 int varid;
00248 const char *name = v->getName().c_str();
00249 size_t start[2], count[2];
00250
00254 start[0] = index; start[1] = 0;
00258 count[0] = 1; count[1] = v->get().size();
00259
00260 retval = nc_inq_varid(ncid, name, &varid);
00261 if (retval)
00262 log(Error) << "Could not get variable id of " << name << ", error " << retval <<endlog();
00263
00264 retval = nc_put_vara_double(ncid, varid, start, count, &(v->get().front()));
00265 if(retval)
00266 log(Error) << "Could not write variable " << name << ", error " << retval <<endlog();
00267
00268 }
00269
00270 std::string composeName(std::string propertyName)
00271 {
00272 std::string prefix_name;
00273
00274 if( propertyName.empty() ) {
00275 nameless_counter++;
00276 prefix_name = prefix + boost::lexical_cast<std::string>( nameless_counter );
00277 }
00278 else {
00279 nameless_counter = 0;
00280 prefix_name = propertyName;
00281 }
00282 return prefix_name;
00283 }
00284
00288 virtual void flush()
00289 {
00290 index++;
00291 }
00292
00293 };
00294 }
00295 #endif