00001 #ifndef PI_PROPERTIES_NETCDFHEADER_SERIALIZER
00002 #define PI_PROPERTIES_NETCDFHEADER_SERIALIZER
00003
00004 #include <rtt/Property.hpp>
00005 #include <boost/lexical_cast.hpp>
00006
00007 #include <netcdf.h>
00008
00009 #define DIMENSION_VAR 1
00010 #define DIMENSION_ARRAY 2
00011
00012 namespace RTT
00013 {
00017 class NetcdfHeaderMarshaller
00018 : public marsh::MarshallInterface
00019 {
00020 int nameless_counter;
00021 std::string prefix;
00022 int ncid;
00023 int dimsid;
00024 int ncopen;
00025
00026 public:
00027
00028 NetcdfHeaderMarshaller(int ncid, int dimsid) : ncid( ncid ), dimsid(dimsid), ncopen(0) {}
00029
00030 virtual ~NetcdfHeaderMarshaller() {}
00031
00032 virtual void serialize(base::PropertyBase* v)
00033 {
00034 Property<PropertyBag>* bag = dynamic_cast< Property<PropertyBag>* >( v );
00035 if ( bag )
00036 this->serialize( *bag );
00037 else {
00038 Property<char>* Pc = dynamic_cast< Property<char>* >( v );
00039 if ( Pc )
00040 {
00041 store(Pc);
00042 return;
00043 }
00044 Property<short>* Ps = dynamic_cast< Property<short>* >( v );
00045 if (Ps)
00046 {
00047 store(Ps);
00048 return;
00049 }
00050 Property<int>* Pi = dynamic_cast< Property<int>* >( v );
00051 if (Pi)
00052 {
00053 store(Pi);
00054 return;
00055 }
00056 Property<float>* Pf = dynamic_cast< Property<float>* >( v );
00057 if (Pf)
00058 {
00059 store(Pf);
00060 return;
00061 }
00062 Property<double>* Pd = dynamic_cast< Property<double>* >( v );
00063 if (Pd)
00064 {
00065 store(Pd);
00066 return;
00067 }
00068 Property<std::vector<double> >* Pv = dynamic_cast< Property<std::vector<double> >* >( v );
00069 if (Pv)
00070 {
00071 store(Pv);
00072 return;
00073 }
00074 }
00075 }
00076
00077 virtual void serialize(const PropertyBag &v)
00078 {
00079 int retval;
00080
00085 if ( ncopen ) {
00086 ncopen++;
00087 }
00088 else {
00089 retval = nc_redef(ncid);
00090 if ( retval )
00091 log(Error) << "Could not enter define mode in NetcdfHeaderMarshaller, error "<< retval <<endlog();
00092 else
00093 ncopen++;
00094 }
00095
00096 for (
00097 PropertyBag::const_iterator i = v.getProperties().begin();
00098 i != v.getProperties().end();
00099 i++ )
00100 {
00101 this->serialize(*i);
00102 }
00103
00107 if (--ncopen)
00108 log(Info) << "Serializer still in progress" <<endlog();
00109 else {
00110 retval = nc_enddef(ncid);
00111 if (retval)
00112 log(Error) << "Could not leave define mode, error" << retval <<endlog();
00113 }
00114 }
00115
00116 virtual void serialize(const Property<PropertyBag> &v)
00117 {
00118 std::string oldpref = prefix;
00119
00120
00121 if(prefix.empty())
00122 prefix = v.getName();
00123 else
00124 prefix += "." + v.getName();
00125
00126 serialize(v.get());
00127
00128 prefix = oldpref;
00129 nameless_counter = 0;
00130 }
00131
00135 void store(Property<char> *v)
00136 {
00137 int retval;
00138 int varid;
00139 std::string sname = composeName(v->getName());
00140
00144 retval = nc_def_var(ncid, sname.c_str(), NC_BYTE, DIMENSION_VAR,
00145 &dimsid, &varid);
00146 if ( retval )
00147 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00148 else
00149 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00150 }
00151
00155 void store(Property<short> *v)
00156 {
00157 int retval;
00158 int varid;
00159 std::string sname = composeName(v->getName());
00160
00164 retval = nc_def_var(ncid, sname.c_str(), NC_SHORT, DIMENSION_VAR,
00165 &dimsid, &varid);
00166 if ( retval )
00167 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00168 else
00169 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00170 }
00171
00175 void store(Property<int> *v)
00176 {
00177 int retval;
00178 int varid;
00179 std::string sname = composeName(v->getName());
00180
00184 retval = nc_def_var(ncid, sname.c_str(), NC_INT, DIMENSION_VAR,
00185 &dimsid, &varid);
00186 if ( retval )
00187 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00188 else
00189 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00190 }
00191
00195 void store(Property<float> *v)
00196 {
00197 int retval;
00198 int varid;
00199 std::string sname = composeName(v->getName());
00200
00204 retval = nc_def_var(ncid, sname.c_str(), NC_FLOAT, DIMENSION_VAR,
00205 &dimsid, &varid);
00206 if ( retval )
00207 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00208 else
00209 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00210 }
00211
00215 void store(Property<double> *v)
00216 {
00217 int retval;
00218 int varid;
00219 std::string sname = composeName(v->getName());
00220
00224 retval = nc_def_var(ncid, sname.c_str(), NC_DOUBLE, DIMENSION_VAR,
00225 &dimsid, &varid);
00226
00227 if ( retval )
00228 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00229 else
00230 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00231 }
00232
00236 void store(Property<std::vector<double> > *v)
00237 {
00238 int retval;
00239 int varid;
00240
00241 std::string dim_name = v->getName().c_str();
00242 dim_name += "_dim";
00243 const char *dimname = dim_name.c_str();
00244
00245 const char *name = v->getName().c_str();
00246
00247 int dims[ DIMENSION_ARRAY ];
00248 int var_dim;
00249
00250
00251 retval = nc_def_dim(ncid, dimname, v->get().size(), &var_dim);
00252 if ( retval )
00253 log(Error) << "Could not create new dimension for "<< dimname <<", error "<< retval <<endlog();
00254
00255
00256 dims[0] = dimsid;
00257 dims[1] = var_dim;
00258
00259 retval = nc_def_var(ncid, name, NC_DOUBLE, DIMENSION_ARRAY,
00260 dims, &varid);
00261 if ( retval )
00262 log(Error) << "Could not create " << name << ", error " << retval <<endlog();
00263 else
00264 log(Info) << "Variable "<< name << " successfully created" <<endlog();
00265 }
00266
00267 std::string composeName(std::string propertyName)
00268 {
00269 std::string prefix_name;
00270
00271 if( propertyName.empty() ) {
00272 nameless_counter++;
00273 prefix_name = prefix + boost::lexical_cast<std::string>( nameless_counter );
00274 }
00275 else {
00276 nameless_counter = 0;
00277 prefix_name = propertyName;
00278 }
00279 return prefix_name;
00280 }
00281
00282 virtual void flush() {}
00283 };
00284 }
00285 #endif