OrocosComponentLibrary  2.7.0
NetcdfMarshaller.hpp
00001 #ifndef PI_PROPERTIES_NETCDFTABLESERIALIZER
00002 #define PI_PROPERTIES_NETCDFTABLESERIALIZER
00003 
00004 #include <rtt/Property.hpp>
00005 #include <rtt/base/PropertyIntrospection.hpp>
00006 #include <boost/lexical_cast.hpp>
00007 
00008 #include <netcdf.h>
00009 #include <iostream>
00010 using namespace std;
00011 
00012 namespace RTT
00013 {
00014 
00020     class NetcdfMarshaller 
00021         : public marsh::MarshallInterface
00022     {
00023       int ncid;
00024       size_t index;
00025       int nameless_counter;
00026       std::string prefix;
00027       
00028       public:
00033         NetcdfMarshaller(int ncid) :
00034           ncid ( ncid ) {index=0;}
00035 
00036         virtual ~NetcdfMarshaller() {}
00037 
00038         virtual void serialize(base::PropertyBase* v) 
00039         { 
00040          Property<PropertyBag>* bag = dynamic_cast< Property<PropertyBag>* >( v );
00041          if ( bag )
00042            this->serialize( *bag );
00043          else {
00044            Property<char>* Pc = dynamic_cast< Property<char>* >( v );
00045            if ( Pc )
00046              {
00047                store(Pc);
00048                return;
00049              }
00050            Property<short>* Ps = dynamic_cast< Property<short>* >( v );
00051            if ( Ps )
00052              {
00053                store(Ps);
00054                return;
00055              }
00056            Property<int>* Pi = dynamic_cast< Property<int>* >( v );
00057            if (Pi)
00058              {
00059                store(Pi);
00060                return;
00061              }
00062            Property<float>* Pf = dynamic_cast< Property<float>* >( v );
00063            if (Pf)
00064              {
00065                store(Pf);
00066                return;
00067              }
00068            Property<double>* Pd = dynamic_cast< Property<double>* >( v );
00069            if (Pd)
00070              {
00071                store(Pd);
00072                return;
00073              }
00074            Property<std::vector<double> >* Pv = dynamic_cast< Property<std::vector<double> >* >( v );
00075            if (Pv)
00076              {
00077                store(Pv);
00078                return;
00079              }
00080          }
00081         }
00082                         
00083         virtual void serialize(const PropertyBag &v) 
00084         {
00085           for (
00086             PropertyBag::const_iterator i = v.getProperties().begin();
00087             i != v.getProperties().end();
00088             i++ )
00089             {
00090               this->serialize( *i );
00091             }
00092         }
00093 
00094         virtual void serialize(const Property<PropertyBag> &v) 
00095         {
00096           std::string oldpref = prefix;
00097 
00098           // Avoid a "." in the beginning of a variable name
00099           if(prefix.empty())
00100             prefix = v.getName();
00101           else
00102             prefix += "." + v.getName();
00103 
00104           serialize(v.rvalue());
00105 
00106           prefix = oldpref;
00107           nameless_counter = 0;
00108         }
00109 
00113         void store(Property<char> *v)
00114         {
00115           int retval;
00116           int varid;
00117           signed char value = v->rvalue();
00118           std::string sname = composeName(v->getName());
00119 
00123           retval = nc_inq_varid(ncid, sname.c_str(), &varid);
00124           if (retval)
00125             log(Error) << "Could not get variable id of " << sname << ", error " << retval <<endlog();
00126 
00130           retval = nc_put_var1_schar(ncid, varid, &index, &value);
00131           if(retval)
00132             log(Error) << "Could not write variable " << sname << ", error " << retval <<endlog();
00133         }
00134 
00138         void store(Property<short> *v)
00139         {
00140 
00141           int retval;
00142           int varid;
00143           short value = v->rvalue();
00144           std::string sname = composeName(v->getName());
00145 
00149           retval = nc_inq_varid(ncid, sname.c_str(), &varid);
00150           if (retval)
00151             log(Error) << "Could not get variable id of " << sname << ", error " << retval <<endlog();
00152 
00156           retval = nc_put_var1_short(ncid, varid, &index, &value);
00157           if(retval)
00158             log(Error) << "Could not write variable " << sname << ", error " << retval <<endlog();
00159         }
00160 
00164         void store(Property<int> *v)
00165         {
00166           int retval;
00167           int varid;
00168           int value = v->rvalue();
00169           std::string sname = composeName(v->getName());
00170 
00174           retval = nc_inq_varid(ncid, sname.c_str(), &varid);
00175           if (retval)
00176             log(Error) << "Could not get variable id of " << sname << ", error " << retval <<endlog();
00177 
00181           retval = nc_put_var1_int(ncid, varid, &index, &value);
00182           if(retval)
00183             log(Error) << "Could not write variable " << sname << ", error " << retval <<endlog();
00184         }
00185 
00189         void store(Property<float> *v)
00190         {
00191           int retval;
00192           int varid;
00193           float value = v->rvalue();
00194           std::string sname = composeName(v->getName());
00195 
00199           retval = nc_inq_varid(ncid, sname.c_str(), &varid);
00200           if (retval)
00201             log(Error) << "Could not get variable id of " << sname << ", error " << retval <<endlog();
00202 
00206           retval = nc_put_var1_float(ncid, varid, &index, &value);
00207           if(retval)
00208             log(Error) << "Could not write variable " << sname << ", error " << retval <<endlog();
00209 
00210         }
00211 
00215         void store(Property<double> *v)
00216         {
00217           int retval;
00218           int varid;
00219           double value = v->rvalue();
00220           std::string sname = composeName(v->getName());
00221 
00225           retval = nc_inq_varid(ncid, sname.c_str(), &varid);
00226           if (retval)
00227             log(Error) << "Could not get variable id of " << sname << ", error " << retval <<endlog();
00228 
00232           retval = nc_put_var1_double(ncid, varid, &index, &value);
00233           if(retval)
00234             log(Error) << "Could not write variable " << sname << ", error " << retval <<endlog();
00235         }    
00236 
00240         void store(Property<std::vector<double> > *v)
00241         {
00242           int retval;
00243           int varid;
00244           const char *name = v->getName().c_str();
00245           size_t start[2], count[2];
00246 
00250           start[0] = index; start[1] = 0;
00254           count[0] = 1; count[1] = v->rvalue().size();
00255 
00256           retval = nc_inq_varid(ncid, name, &varid);
00257           if (retval)
00258             log(Error) << "Could not get variable id of " << name << ", error " << retval <<endlog();
00259 
00260           retval = nc_put_vara_double(ncid, varid, start, count, &(v->rvalue().front()));
00261           if(retval)
00262             log(Error) << "Could not write variable " << name << ", error " << retval <<endlog();
00263 
00264         }
00265 
00266         std::string composeName(std::string propertyName)
00267         {
00268           std::string last_name;
00269 
00270           if( propertyName.empty() ) {
00271             nameless_counter++;
00272             last_name = boost::lexical_cast<std::string>( nameless_counter );
00273           }
00274           else {
00275             nameless_counter = 0;
00276             last_name = propertyName;
00277           }
00278           if ( prefix.empty() )
00279             return last_name;
00280           else
00281             return prefix + "." + last_name;
00282         }
00283 
00287         virtual void flush() 
00288         {
00289           index++;
00290         }
00291 
00292      };
00293 }
00294 #endif