Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "CPFMarshaller.hpp"
00040 #include "../rtt-config.h"
00041
00042 #include <iostream>
00043 using namespace std;
00044 namespace RTT {
00045 using namespace detail;
00046 template<class T>
00047 void CPFMarshaller<std::ostream>::doWrite( const Property<T> &v, const std::string& type )
00048 {
00049 *(this->s) <<indent << "<simple ";
00050 if ( !v.getName().empty() )
00051 *(this->s) <<"name=\"" << this->escape( v.getName() ) <<"\" ";
00052 *(this->s) << "type=\""<< type <<"\">";
00053 if ( !v.getDescription().empty() )
00054 *(this->s) << "<description>"<< this->escape( v.getDescription() ) << "</description>";
00055 *(this->s) << "<value>" << v.get() << "</value></simple>\n";
00056 }
00057
00058 void CPFMarshaller<std::ostream>::doWrite( const Property<std::string> &v, const std::string& type )
00059 {
00060 *(this->s) <<indent << "<simple ";
00061 if ( !v.getName().empty() )
00062 *(this->s) <<"name=\"" << this->escape( v.getName() ) <<"\" ";
00063 *(this->s) << "type=\""<< type <<"\">";
00064 if ( !v.getDescription().empty() )
00065 *(this->s) << "<description>"<< this->escape( v.getDescription() ) << "</description>";
00066 *(this->s) << "<value>" << this->escape( v.get() ) << "</value></simple>\n";
00067 }
00068
00069
00070 void CPFMarshaller<std::ostream>::doWrite( const Property<char> &v, const std::string& type )
00071 {
00072 *(this->s) <<indent << "<simple ";
00073 if ( !v.getName().empty() )
00074 *(this->s) <<"name=\"" << this->escape( v.getName() ) <<"\" ";
00075 *(this->s) << "type=\""<< type <<"\">";
00076 if ( !v.getDescription().empty() )
00077 *(this->s) << "<description>"<< this->escape( v.getDescription() ) << "</description>";
00078 if ( v.get() == '\0' )
00079 *(this->s)<< "<value></value></simple>\n";
00080 else {
00081 std::string toescape(1, v.get());
00082 *(this->s) << "<value>" << this->escape( toescape ) << "</value></simple>\n";
00083 }
00084 }
00085
00086
00087 std::string CPFMarshaller<std::ostream>::escape(std::string s)
00088 {
00089 std::string::size_type n=0;
00090
00091 while ((n = s.find("&",n)) != s.npos) {
00092 s.replace(n, 1, std::string("&"));
00093 n += 5;
00094 }
00095
00096 n=0;
00097 while ((n = s.find("<",n)) != s.npos) {
00098 s.replace(n, 1, std::string("<"));
00099 n += 4;
00100 }
00101
00102 n=0;
00103 while ((n = s.find(">",n)) != s.npos) {
00104 s.replace(n, 1, std::string(">"));
00105 n += 4;
00106 }
00107
00108
00109 return s;
00110 }
00111
00112
00113 void CPFMarshaller<std::ostream>::introspect(PropertyBase* pb)
00114 {
00115 if (dynamic_cast<Property<unsigned char>* >(pb) )
00116 return introspect( *static_cast<Property<unsigned char>* >(pb) );
00117 if (dynamic_cast<Property<float>* >(pb) )
00118 return introspect( *static_cast<Property<float>* >(pb) );
00119
00120
00121
00122
00123
00124
00125
00126
00127 log(Error) << "Couldn't write "<< pb->getName() << " to XML file because the " << pb->getType() << " type is not supported by the CPF format." <<endlog();
00128 log(Error) << "If your type is a C++ struct or sequence, you can register it with a type info object." <<endlog();
00129 log(Error) << "We only support these primitive types: boolean|char|double|float|long|octet|string|ulong." <<endlog();
00130 }
00131
00132
00133 void CPFMarshaller<std::ostream>::introspect(Property<bool> &v)
00134 {
00135 doWrite( v, "boolean");
00136 }
00137
00138
00139 void CPFMarshaller<std::ostream>::introspect(Property<char> &v)
00140 {
00141 doWrite( v, "char");
00142 }
00143
00144 void CPFMarshaller<std::ostream>::introspect(Property<unsigned char> &v)
00145 {
00146 doWrite( v, "octet");
00147 }
00148
00149
00150 void CPFMarshaller<std::ostream>::introspect(Property<int> &v)
00151 {
00152 doWrite( v, "long");
00153 }
00154
00155
00156 void CPFMarshaller<std::ostream>::introspect(Property<unsigned int> &v)
00157 {
00158 doWrite( v, "ulong");
00159 }
00160
00161 void CPFMarshaller<std::ostream>::introspect(Property<short> &v)
00162 {
00163 doWrite( v, "short");
00164 }
00165
00166
00167 void CPFMarshaller<std::ostream>::introspect(Property<unsigned short> &v)
00168 {
00169 doWrite( v, "ushort");
00170 }
00171
00172 void CPFMarshaller<std::ostream>::introspect(Property<float> &v)
00173 {
00174 (this->s)->precision(15);
00175 doWrite( v, "float");
00176 }
00177
00178 void CPFMarshaller<std::ostream>::introspect(Property<double> &v)
00179 {
00180 (this->s)->precision(25);
00181 doWrite( v, "double");
00182 }
00183
00184
00185 void CPFMarshaller<std::ostream>::introspect(Property<std::string> &v)
00186 {
00187 doWrite( v, "string");
00188 }
00189
00190
00191 void CPFMarshaller<std::ostream>::introspect(Property<PropertyBag> &b)
00192 {
00193 PropertyBag v = b.get();
00194 *(this->s) <<indent<<"<struct name=\""<<escape(b.getName())<<"\" type=\""<< escape(v.getType())<< "\">\n";
00195 indent +=" ";
00196 if ( !b.getDescription().empty() )
00197 *(this->s) <<indent<<"<description>" <<escape(b.getDescription()) << "</description>\n";
00198
00199 b.value().identify(this);
00200
00201 indent = indent.substr(0, indent.length()-3);
00202 *(this->s) <<indent<<"</struct>\n";
00203 }
00204
00205 CPFMarshaller<std::ostream>::CPFMarshaller(std::ostream &os)
00206 : StreamProcessor<std::ostream>(os), indent(" ")
00207 {
00208 }
00209
00210 CPFMarshaller<std::ostream>::CPFMarshaller(const std::string& filename)
00211 : StreamProcessor<std::ostream>(mfile),
00212 mfile(filename.c_str(), std::fstream::out),
00213 indent(" ")
00214 {
00215 if ( !mfile ) {
00216 s = 0;
00217 log(Error) << "Could not open file for writing: "<<filename <<endlog();
00218 }
00219 }
00220
00221
00222 void CPFMarshaller<std::ostream>::serialize(PropertyBase* v)
00223 {
00224 if (s)
00225 v->identify( this );
00226 }
00227
00228
00229 void CPFMarshaller<std::ostream>::serialize(const PropertyBag &v)
00230 {
00231 if ( !s )
00232 return;
00233 *(this->s) <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00234 <<"<!DOCTYPE properties SYSTEM \"cpf.dtd\">\n";
00235 *(this->s) <<"<properties>\n";
00236
00237 v.identify(this);
00238
00239 *(this->s) << "</properties>\n";
00240 }
00241
00242
00243 void CPFMarshaller<std::ostream>::flush()
00244 {
00245 if (s)
00246 this->s->flush();
00247 }
00248 }
00249