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 Marshaller
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(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 Property<PropertyBag> bag( v->getName(), "");
00076 v->getTypeInfo()->decomposeType( v->getDataSource(), bag.value() );
00077 this->serialize( bag );
00078 deleteProperties( bag.value() );
00079
00080 }
00081 }
00082
00083 virtual void serialize(const PropertyBag &v)
00084 {
00085 int retval;
00086
00091 if ( ncopen ) {
00092 ncopen++;
00093 }
00094 else {
00095 retval = nc_redef(ncid);
00096 if ( retval )
00097 log(Error) << "Could not enter define mode in NetcdfHeaderMarshaller, error "<< retval <<endlog();
00098 else
00099 ncopen++;
00100 }
00101
00102 for (
00103 PropertyBag::const_iterator i = v.getProperties().begin();
00104 i != v.getProperties().end();
00105 i++ )
00106 {
00107 this->serialize(*i);
00108 }
00109
00113 if (--ncopen)
00114 log(Info) << "Serializer still in progress" <<endlog();
00115 else {
00116 retval = nc_enddef(ncid);
00117 if (retval)
00118 log(Error) << "Could not leave define mode, error" << retval <<endlog();
00119 }
00120 }
00121
00122 virtual void serialize(const Property<PropertyBag> &v)
00123 {
00124 std::string oldpref = prefix;
00125
00126
00127 if(prefix.empty())
00128 prefix = v.getName();
00129 else
00130 prefix += "." + v.getName();
00131
00132 serialize(v.get());
00133
00134 prefix = oldpref;
00135 nameless_counter = 0;
00136 }
00137
00141 void store(Property<char> *v)
00142 {
00143 int retval;
00144 int varid;
00145 std::string sname = composeName(v->getName());
00146
00150 retval = nc_def_var(ncid, sname.c_str(), NC_BYTE, DIMENSION_VAR,
00151 &dimsid, &varid);
00152 if ( retval )
00153 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00154 else
00155 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00156 }
00157
00161 void store(Property<short> *v)
00162 {
00163 int retval;
00164 int varid;
00165 std::string sname = composeName(v->getName());
00166
00170 retval = nc_def_var(ncid, sname.c_str(), NC_SHORT, DIMENSION_VAR,
00171 &dimsid, &varid);
00172 if ( retval )
00173 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00174 else
00175 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00176 }
00177
00181 void store(Property<int> *v)
00182 {
00183 int retval;
00184 int varid;
00185 std::string sname = composeName(v->getName());
00186
00190 retval = nc_def_var(ncid, sname.c_str(), NC_INT, DIMENSION_VAR,
00191 &dimsid, &varid);
00192 if ( retval )
00193 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00194 else
00195 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00196 }
00197
00201 void store(Property<float> *v)
00202 {
00203 int retval;
00204 int varid;
00205 std::string sname = composeName(v->getName());
00206
00210 retval = nc_def_var(ncid, sname.c_str(), NC_FLOAT, DIMENSION_VAR,
00211 &dimsid, &varid);
00212 if ( retval )
00213 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00214 else
00215 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00216 }
00217
00221 void store(Property<double> *v)
00222 {
00223 int retval;
00224 int varid;
00225 std::string sname = composeName(v->getName());
00226
00230 retval = nc_def_var(ncid, sname.c_str(), NC_DOUBLE, DIMENSION_VAR,
00231 &dimsid, &varid);
00232
00233 if ( retval )
00234 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
00235 else
00236 log(Info) << "Variable "<< sname << " successfully created" <<endlog();
00237 }
00238
00242 void store(Property<std::vector<double> > *v)
00243 {
00244 int retval;
00245 int varid;
00246
00247 std::string dim_name = v->getName().c_str();
00248 dim_name += "_dim";
00249 const char *dimname = dim_name.c_str();
00250
00251 const char *name = v->getName().c_str();
00252
00253 int dims[ DIMENSION_ARRAY ];
00254 int var_dim;
00255
00256
00257 retval = nc_def_dim(ncid, dimname, v->get().size(), &var_dim);
00258 if ( retval )
00259 log(Error) << "Could not create new dimension for "<< dimname <<", error "<< retval <<endlog();
00260
00261
00262 dims[0] = dimsid;
00263 dims[1] = var_dim;
00264
00265 retval = nc_def_var(ncid, name, NC_DOUBLE, DIMENSION_ARRAY,
00266 dims, &varid);
00267 if ( retval )
00268 log(Error) << "Could not create " << name << ", error " << retval <<endlog();
00269 else
00270 log(Info) << "Variable "<< name << " successfully created" <<endlog();
00271 }
00272
00273 std::string composeName(std::string propertyName)
00274 {
00275 std::string prefix_name;
00276
00277 if( propertyName.empty() ) {
00278 nameless_counter++;
00279 prefix_name = prefix + boost::lexical_cast<std::string>( nameless_counter );
00280 }
00281 else {
00282 nameless_counter = 0;
00283 prefix_name = propertyName;
00284 }
00285 return prefix_name;
00286 }
00287
00288 virtual void flush() {}
00289 };
00290 }
00291 #endif