|
Urbi SDK Remote for C++
2.7.3
|
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