Urbi SDK Remote for C++  2.7.5
uvalue-serialize.hh
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011, Gostai S.A.S.
00003  *
00004  * This software is provided "as is" without warranty of any kind,
00005  * either expressed or implied, including but not limited to the
00006  * implied warranties of fitness for a particular purpose.
00007  *
00008  * See the LICENSE file for more information.
00009  */
00010 
00011 /* Serialization/deserialization of UValue to/from a binary stream.
00012  */
00013 #include <libport/lexical-cast.hh>
00014 #include <serialize/serialize.hh>
00015 #include <urbi/uvalue.hh>
00016 
00017 #ifndef UVALUE_SERIALIZE_HH
00018 #define UVALUE_SERIALIZE_HH
00019 namespace urbi
00020 {
00021   template<class Archive>
00022   void saveUValue(Archive & ar, const urbi::UValue& v, std::ostream& os);
00023   template<class Archive>
00024   void loadUValue(Archive & ar, urbi::UValue& v, std::istream& is);
00025 }
00026 
00027 // libport/serialize functions
00028 namespace libport
00029 {
00030   namespace serialize
00031   {
00032     template<>
00033     struct BinaryOSerializer::Impl<urbi::UValue>
00034     {
00035       static void put(const std::string&,
00036                       const urbi::UValue& v,
00037                       std::ostream& output,
00038                       BinaryOSerializer& ser)
00039       {
00040         saveUValue(ser, v, output);
00041       }
00042     };
00043     template<>
00044     struct BinaryOSerializer::Impl<const urbi::UValue>
00045     {
00046       static void put(const std::string&,
00047                       const urbi::UValue& v,
00048                       std::ostream& output,
00049                       BinaryOSerializer& ser)
00050       {
00051         saveUValue(ser, v, output);
00052       }
00053     };
00054     template<>
00055     struct BinaryISerializer::Impl<urbi::UValue>
00056     {
00057       static urbi::UValue get(const std::string&,
00058                               std::istream& input, BinaryISerializer& ser)
00059       {
00060         urbi::UValue v;
00061         loadUValue(ser, v, input);
00062         return v;
00063       }
00064     };
00065   }
00066 }
00067 
00068 namespace urbi
00069 {
00070 template<class Archive>
00071 void saveUValue(Archive & ar, const urbi::UValue& v, std::ostream& os)
00072 {
00073   unsigned char dt = (unsigned char)v.type;
00074   ar << dt;
00075   switch(v.type)
00076   {
00077   case urbi::DATA_BINARY:
00078     {
00079       std::string m =  v.binary->getMessage();
00080       unsigned int s = v.binary->common.size;
00081       ar << m << s;
00082       os.write((const char*)v.binary->common.data, v.binary->common.size);
00083     }
00084     break;
00085 
00086   case urbi::DATA_DICTIONARY:
00087     {
00088       unsigned int len =  v.dictionary->size();
00089       ar << len;
00090       foreach(urbi::UDictionary::value_type& e, *v.dictionary)
00091         ar << e.first << e.second;
00092     }
00093     break;
00094 
00095   case urbi::DATA_DOUBLE:
00096     ar << v.val;
00097     break;
00098 
00099   case urbi::DATA_LIST:
00100     {
00101       unsigned int len = v.list->size();
00102       ar << len;
00103       for (unsigned i=0; i<v.list->size(); ++i)
00104         ar << *v.list->array[i];
00105     }
00106     break;
00107 
00108   case urbi::DATA_STRING:
00109   case urbi::DATA_SLOTNAME:
00110     ar << *v.stringValue;
00111     break;
00112 
00113   case urbi::DATA_VOID:
00114     break;
00115 
00116   default:
00117     throw std::runtime_error("Unsupported UValue type");
00118   }
00119 }
00120 
00121 template<class Archive>
00122 void loadUValue(Archive & ar, urbi::UValue& v, std::istream& is)
00123 {
00124   v.clear();
00125   unsigned char dt;
00126   ar >> dt;
00127   unsigned int sz;
00128   std::string s;
00129   switch((urbi::UDataType)dt)
00130   {
00131   case urbi::DATA_BINARY:
00132   {
00133     std::string headers;
00134     ar >> headers;
00135     ar >> sz;
00136     void* data = malloc(sz);
00137     is.read((char*)data, sz);
00138     urbi::binaries_type bins;
00139     bins.push_back(urbi::BinaryData(data, sz));
00140     v.type = urbi::DATA_BINARY;
00141     v.binary = new urbi::UBinary;
00142     urbi::binaries_type::const_iterator i = bins.begin();
00143     headers = (string_cast(sz)
00144                + (headers.empty() ? "" : " ")
00145                + headers +";");
00146     v.binary->parse(headers.c_str(), 0, bins, i, false);
00147     v.binary->allocated_ = true;
00148   }
00149   break;
00150 
00151   case urbi::DATA_DICTIONARY:
00152     ar >> sz;
00153     v = urbi::UDictionary();
00154     for (size_t i=0; i<sz; ++i)
00155     {
00156       std::string key;
00157       ar >> key;
00158       ar >> (*v.dictionary)[key];
00159     }
00160     break;
00161 
00162   case urbi::DATA_DOUBLE:
00163     {
00164       v.type = urbi::DATA_DOUBLE;
00165       ufloat val;
00166       ar >> val;
00167       v = val;
00168     }
00169     break;
00170 
00171   case urbi::DATA_LIST:
00172     ar >> sz;
00173     v = urbi::UList();
00174     for (size_t i=0; i<sz; ++i)
00175     {
00176       urbi::UValue* val = new urbi::UValue;
00177       ar >> *val;
00178       v.list->array.push_back(val);
00179     }
00180     break;
00181 
00182   case urbi::DATA_STRING:
00183   case urbi::DATA_SLOTNAME:
00184     ar >> s;
00185     v = s;
00186     v.type = (urbi::UDataType)dt;
00187     break;
00188 
00189   case urbi::DATA_VOID:
00190     v.type = urbi::DATA_VOID;
00191     break;
00192 
00193   default:
00194     throw std::runtime_error("Unsupported serialized UValue type");
00195   }
00196 }
00197 }
00198 #endif