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 #include <iostream>
00013 using namespace std;
00014
00015 namespace RTT
00016 {
00020 class NetcdfHeaderMarshaller
00021 : public marsh::MarshallInterface
00022 {
00023 int nameless_counter;
00024 std::string prefix;
00025 int ncid;
00026 int dimsid;
00027 int ncopen;
00028
00029 public:
00030
00031 NetcdfHeaderMarshaller(int ncid, int dimsid) : ncid( ncid ), dimsid(dimsid), ncopen(0) {}
00032
00033 virtual ~NetcdfHeaderMarshaller() {}
00034
00035 virtual void serialize(base::PropertyBase* v)
00036 {
00037 Property<PropertyBag>* bag = dynamic_cast< Property<PropertyBag>* >( v );
00038 if ( bag )
00039 this->serialize( *bag );
00040 else {
00041 Property<char>* Pc = dynamic_cast< Property<char>* >( v );
00042 if ( Pc )
00043 {
00044 store(Pc);
00045 return;
00046 }
00047 Property<short>* Ps = dynamic_cast< Property<short>* >( v );
00048 if (Ps)
00049 {
00050 store(Ps);
00051 return;
00052 }
00053 Property<int>* Pi = dynamic_cast< Property<int>* >( v );
00054 if (Pi)
00055 {
00056 store(Pi);
00057 return;
00058 }
00059 Property<float>* Pf = dynamic_cast< Property<float>* >( v );
00060 if (Pf)
00061 {
00062 store(Pf);
00063 return;
00064 }
00065 Property<double>* Pd = dynamic_cast< Property<double>* >( v );
00066 if (Pd)
00067 {
00068 store(Pd);
00069 return;
00070 }
00071 Property<std::vector<double> >* Pv = dynamic_cast< Property<std::vector<double> >* >( v );
00072 if (Pv)
00073 {
00074 store(Pv);
00075 return;
00076 }
00077 }
00078 }
00079
00080 virtual void serialize(const PropertyBag &v)
00081 {
00082 int retval;
00083
00088 if ( ncopen ) {
00089 ncopen++;
00090 }
00091 else {
00092 retval = nc_redef(ncid);
00093 if ( retval )
00094 log(Error) << "Could not enter define mode in NetcdfHeaderMarshaller, error "<< retval <<endlog();
00095 else
00096 ncopen++;
00097 }
00098
00099 for (
00100 PropertyBag::const_iterator i = v.getProperties().begin();
00101 i != v.getProperties().end();
00102 i++ )
00103 {
00104 this->serialize(*i);
00105 }
00106
00110 if (--ncopen)
00111 log(Info) << "Serializer still in progress" <<endlog();
00112 else {
00113 retval = nc_enddef(ncid);
00114 if (retval)
00115 log(Error) << "Could not leave define mode, error" << retval <<endlog();
00116 }
00117 }
00118
00119 virtual void serialize(const Property<PropertyBag> &v)
00120 {
00121 std::string oldpref = prefix;
00122
00123
00124 if(prefix.empty())
00125 prefix = v.getName();
00126 else
00127 prefix += "." + v.getName();
00128
00129 serialize(v.rvalue());
00130
00131 prefix = oldpref;
00132 nameless_counter = 0;
00133 }
00134
00138 void store(Property<char> *v)
00139 {
00140 int retval;
00141 int varid;
00142 std::string sname = composeName(v->getName());
00143
00147 retval = nc_def_var(ncid, sname.c_str(), NC_BYTE, DIMENSION_VAR,
00148 &dimsid, &varid);
00149 if ( retval )
00150 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00151 else
00152 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00153 }
00154
00158 void store(Property<short> *v)
00159 {
00160 int retval;
00161 int varid;
00162 std::string sname = composeName(v->getName());
00163
00167 retval = nc_def_var(ncid, sname.c_str(), NC_SHORT, DIMENSION_VAR,
00168 &dimsid, &varid);
00169 if ( retval )
00170 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00171 else
00172 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00173 }
00174
00178 void store(Property<int> *v)
00179 {
00180 int retval;
00181 int varid;
00182 std::string sname = composeName(v->getName());
00183
00187 retval = nc_def_var(ncid, sname.c_str(), NC_INT, DIMENSION_VAR,
00188 &dimsid, &varid);
00189 if ( retval )
00190 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00191 else
00192 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00193 }
00194
00198 void store(Property<float> *v)
00199 {
00200 int retval;
00201 int varid;
00202 std::string sname = composeName(v->getName());
00203
00207 retval = nc_def_var(ncid, sname.c_str(), NC_FLOAT, DIMENSION_VAR,
00208 &dimsid, &varid);
00209 if ( retval )
00210 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00211 else
00212 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00213 }
00214
00218 void store(Property<double> *v)
00219 {
00220 int retval;
00221 int varid;
00222 std::string sname = composeName(v->getName());
00223
00227 retval = nc_def_var(ncid, sname.c_str(), NC_DOUBLE, DIMENSION_VAR,
00228 &dimsid, &varid);
00229
00230 if ( retval )
00231 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00232 else
00233 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00234 }
00235
00239 void store(Property<std::vector<double> > *v)
00240 {
00241 int retval;
00242 int varid;
00243
00244 std::string dim_name = v->getName().c_str();
00245 dim_name += "_dim";
00246 const char *dimname = dim_name.c_str();
00247
00248 const char *name = v->getName().c_str();
00249
00250 int dims[ DIMENSION_ARRAY ];
00251 int var_dim;
00252
00253
00254 retval = nc_def_dim(ncid, dimname, v->rvalue().size(), &var_dim);
00255 if ( retval )
00256 log(Error) << "Could not create new dimension for "<< dimname <<", error "<< retval <<endlog();
00257
00258
00259 dims[0] = dimsid;
00260 dims[1] = var_dim;
00261
00262 retval = nc_def_var(ncid, name, NC_DOUBLE, DIMENSION_ARRAY,
00263 dims, &varid);
00264 if ( retval )
00265 log(Error) << "Could not create " << name << ", error " << retval <<endlog();
00266 else
00267 log(Info) << "Variable "<< name << " successfully created" <<endlog();
00268 }
00269
00270 std::string composeName(std::string propertyName)
00271 {
00272 std::string last_name;
00273
00274 if( propertyName.empty() ) {
00275 nameless_counter++;
00276 last_name = boost::lexical_cast<std::string>( nameless_counter );
00277 }
00278 else {
00279 nameless_counter = 0;
00280 last_name = propertyName;
00281 }
00282 if ( prefix.empty() )
00283 return last_name;
00284 else
00285 return prefix + "." + last_name;
00286 }
00287
00288 virtual void flush() {}
00289 };
00290 }
00291 #endif