|
Sierra Toolkit Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 00009 #include <stdexcept> 00010 #include <map> 00011 #include <cstring> 00012 00013 #include <stk_util/util/Marshal.hpp> 00014 00015 namespace stk { 00016 00017 namespace { 00018 00019 typedef std::map<uint32_t, std::string> TypeNameMap; 00020 00021 bool s_crcInitialized = false; 00022 uint32_t s_crcTable[256]; 00023 TypeNameMap s_typeNameMap; 00024 00025 uint32_t 00026 crc32_reflect( 00027 uint32_t seed, 00028 const char c) 00029 { 00030 uint32_t value = 0; 00031 00032 // Swap bit 0 for bit 7, bit 1 For bit 6, etc.... 00033 for(int i = 1; i < (c + 1); i++) { 00034 if (seed & 1) 00035 value |= (1 << (c - i)); 00036 seed >>= 1; 00037 } 00038 00039 return value; 00040 } 00041 00042 00043 void 00044 crc32_initialize() 00045 { 00046 s_crcInitialized = true; 00047 00048 //0x04C11DB7 is the official polynomial used by PKZip, WinZip and Ethernet. 00049 uint32_t polynomial = 0x04C11DB7; 00050 00051 std::fill(s_crcTable, s_crcTable + 256, 0); 00052 00053 // 256 values representing ASCII character codes. 00054 for (int i = 0; i <= 0xFF; i++) { 00055 s_crcTable[i] = crc32_reflect(i, 8) << 24; 00056 00057 for (int j = 0; j < 8; j++) 00058 s_crcTable[i] = (s_crcTable[i] << 1) ^ ((s_crcTable[i] & (1u << 31)) ? polynomial : 0); 00059 00060 s_crcTable[i] = crc32_reflect(s_crcTable[i], 32); 00061 } 00062 } 00063 00064 00065 void 00066 crc32_part( 00067 uint32_t & crc, 00068 const unsigned char * s, 00069 unsigned l) 00070 { 00071 while (l--) 00072 crc = (crc >> 8)^s_crcTable[(crc & 0xFF)^*s++]; 00073 } 00074 00075 00076 uint32_t 00077 crc32( 00078 const unsigned char * s, 00079 unsigned l) 00080 { 00081 uint32_t crc = 0xffffffff; 00082 crc32_part(crc, s, l); 00083 return crc ^ 0xffffffff; 00084 } 00085 00086 00087 void 00088 crc32_write( 00089 std::stringstream & os, 00090 const std::type_info & typeinfo) 00091 { 00092 if (!s_crcInitialized) 00093 crc32_initialize(); 00094 00095 const char *name = typeinfo.name(); 00096 unsigned length = std::strlen(name); 00097 00098 uint32_t crc = crc32((const unsigned char *) name, length); 00099 00100 TypeNameMap::iterator it = s_typeNameMap.find(crc); 00101 if (it == s_typeNameMap.end()) 00102 s_typeNameMap.insert(std::make_pair(crc, std::string(name))); 00103 00104 os.write((const char *) &crc, sizeof(uint32_t)); 00105 } 00106 00107 00108 void 00109 crc32_check( 00110 std::stringstream & is, 00111 const std::type_info & typeinfo) 00112 { 00113 if (!s_crcInitialized) 00114 crc32_initialize(); 00115 00116 const char *name = typeinfo.name(); 00117 unsigned length = std::strlen(name); 00118 00119 uint32_t crc_check = crc32((const unsigned char *) name, length); 00120 uint32_t crc = 0; 00121 00122 { 00123 TypeNameMap::iterator it = s_typeNameMap.find(crc_check); 00124 if (it == s_typeNameMap.end()) 00125 s_typeNameMap.insert(std::make_pair(crc_check, std::string(name))); 00126 } 00127 00128 is.read((char *) &crc, sizeof(uint32_t)); 00129 00130 if (crc_check != crc) { 00131 std::ostringstream ss; 00132 ss << "Marshaller encountered type "; 00133 TypeNameMap::const_iterator it = s_typeNameMap.find(crc); 00134 if (it == s_typeNameMap.end()) 00135 ss << "code " << std::hex << crc; 00136 else 00137 ss << (*it).second; 00138 00139 ss << " when expecting type "; 00140 it = s_typeNameMap.find(crc_check); 00141 if (it == s_typeNameMap.end()) 00142 ss << "code " << std::hex << crc_check; 00143 else 00144 ss << (*it).second; 00145 00146 throw std::runtime_error(ss.str()); 00147 } 00148 } 00149 00150 } // namespace <empty> 00151 00152 Marshal::Marshal( 00153 unsigned type_check) 00154 : stream(std::ios_base::out), 00155 m_typeCheck(TYPE_CHECK_NONE) 00156 { 00157 (*this) << type_check; 00158 m_typeCheck = type_check; 00159 } 00160 00161 00162 Marshal::Marshal( 00163 const std::string & s) 00164 : stream(s, std::ios_base::in), 00165 m_typeCheck(TYPE_CHECK_NONE) 00166 { 00167 (*this) >> m_typeCheck; 00168 } 00169 00170 00171 std::string 00172 Marshal::str() const 00173 { 00174 return stream.str(); 00175 } 00176 00177 00178 size_t 00179 Marshal::size() const 00180 { 00181 return stream.str().size(); 00182 } 00183 00184 00185 Marshal::operator void * () const 00186 { 00187 return static_cast<void *>(stream); 00188 } 00189 00190 00191 void 00192 Marshal::write( 00193 const char * address, 00194 size_t byte_count) 00195 { 00196 stream.write(address, byte_count); 00197 } 00198 00199 00200 void 00201 Marshal::read( 00202 char * address, 00203 size_t byte_count) 00204 { 00205 stream.read(address, byte_count); 00206 } 00207 00208 00209 template<> 00210 Marshal &operator<<(Marshal &mout, const std::type_info &t) { 00211 crc32_write(mout.stream, t); 00212 return mout; 00213 } 00214 00215 template<> 00216 Marshal &operator>>(Marshal &min, const std::type_info &t) { 00217 crc32_check(min.stream, t); 00218 return min; 00219 } 00220 00221 template<> 00222 Marshal &operator<<(Marshal &mout, const signed char &t) { 00223 if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD) 00224 mout << typeid(t); 00225 return write(mout, t); 00226 } 00227 00228 template<> 00229 Marshal &operator<<(Marshal &mout, const unsigned char &t) { 00230 if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD) 00231 mout << typeid(t); 00232 return write(mout, t); 00233 } 00234 00235 template<> 00236 Marshal &operator<<(Marshal &mout, const char &t) { 00237 if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD) 00238 mout << typeid(t); 00239 return write(mout, t); 00240 } 00241 00242 template<> 00243 Marshal &operator<<(Marshal &mout, const short &t) { 00244 if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD) 00245 mout << typeid(t); 00246 return write(mout, t); 00247 } 00248 00249 template<> 00250 Marshal &operator<<(Marshal &mout, const unsigned short &t) { 00251 if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD) 00252 mout << typeid(t); 00253 return write(mout, t); 00254 } 00255 00256 template<> 00257 Marshal &operator<<(Marshal &mout, const int &t) { 00258 if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD) 00259 mout << typeid(t); 00260 return write(mout, t); 00261 } 00262 00263 template<> 00264 Marshal &operator<<(Marshal &mout, const unsigned int &t) { 00265 if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD) 00266 mout << typeid(t); 00267 return write(mout, t); 00268 } 00269 00270 template<> 00271 Marshal &operator<<(Marshal &mout, const long &t) { 00272 if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD) 00273 mout << typeid(t); 00274 return write(mout, t); 00275 } 00276 00277 template<> 00278 Marshal &operator<<(Marshal &mout, const unsigned long &t) { 00279 if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD) 00280 mout << typeid(t); 00281 return write(mout, t); 00282 } 00283 00284 template<> 00285 Marshal &operator<<(Marshal &mout, const long long &t) { 00286 if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD) 00287 mout << typeid(t); 00288 return write(mout, t); 00289 } 00290 00291 template<> 00292 Marshal &operator<<(Marshal &mout, const unsigned long long &t) { 00293 if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD) 00294 mout << typeid(t); 00295 return write(mout, t); 00296 } 00297 00298 template<> 00299 Marshal &operator<<(Marshal &mout, const float &t) { 00300 if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD) 00301 mout << typeid(t); 00302 return write(mout, t); 00303 } 00304 00305 template<> 00306 Marshal &operator<<(Marshal &mout, const double &t) { 00307 if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD) 00308 mout << typeid(t); 00309 return write(mout, t); 00310 } 00311 00312 template<> 00313 Marshal &operator<<(Marshal &mout, const std::string &s) { 00314 if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD) 00315 mout << typeid(s); 00316 00317 size_t ul = s.size(); 00318 mout << ul; 00319 mout.stream.write(s.data(), s.size()); 00320 return mout; 00321 } 00322 00323 00324 template<> 00325 Marshal &operator>>(Marshal &min, signed char &t) { 00326 if (min.m_typeCheck & Marshal::TYPE_CHECK_POD) 00327 min >> typeid(t); 00328 return read(min, t); 00329 } 00330 00331 template<> 00332 Marshal &operator>>(Marshal &min, unsigned char &t) { 00333 if (min.m_typeCheck & Marshal::TYPE_CHECK_POD) 00334 min >> typeid(t); 00335 return read(min, t); 00336 } 00337 00338 template<> 00339 Marshal &operator>>(Marshal &min, char &t) { 00340 if (min.m_typeCheck & Marshal::TYPE_CHECK_POD) 00341 min >> typeid(t); 00342 return read(min, t); 00343 } 00344 00345 template<> 00346 Marshal &operator>>(Marshal &min, short &t) { 00347 if (min.m_typeCheck & Marshal::TYPE_CHECK_POD) 00348 min >> typeid(t); 00349 return read(min, t); 00350 } 00351 00352 template<> 00353 Marshal &operator>>(Marshal &min, unsigned short &t) { 00354 if (min.m_typeCheck & Marshal::TYPE_CHECK_POD) 00355 min >> typeid(t); 00356 return read(min, t); 00357 } 00358 00359 template<> 00360 Marshal &operator>>(Marshal &min, int &t) { 00361 if (min.m_typeCheck & Marshal::TYPE_CHECK_POD) 00362 min >> typeid(t); 00363 return read(min, t); 00364 } 00365 00366 template<> 00367 Marshal &operator>>(Marshal &min, unsigned int &t) { 00368 if (min.m_typeCheck & Marshal::TYPE_CHECK_POD) 00369 min >> typeid(t); 00370 return read(min, t); 00371 } 00372 00373 template<> 00374 Marshal &operator>>(Marshal &min, long &t) { 00375 if (min.m_typeCheck & Marshal::TYPE_CHECK_POD) 00376 min >> typeid(t); 00377 return read(min, t); 00378 } 00379 00380 template<> 00381 Marshal &operator>>(Marshal &min, unsigned long &t) { 00382 if (min.m_typeCheck & Marshal::TYPE_CHECK_POD) 00383 min >> typeid(t); 00384 return read(min, t); 00385 } 00386 00387 template<> 00388 Marshal &operator>>(Marshal &min, long long &t) { 00389 if (min.m_typeCheck & Marshal::TYPE_CHECK_POD) 00390 min >> typeid(t); 00391 return read(min, t); 00392 } 00393 00394 template<> 00395 Marshal &operator>>(Marshal &min, unsigned long long &t) { 00396 if (min.m_typeCheck & Marshal::TYPE_CHECK_POD) 00397 min >> typeid(t); 00398 return read(min, t); 00399 } 00400 00401 template<> 00402 Marshal &operator>>(Marshal &min, float &t) { 00403 if (min.m_typeCheck & Marshal::TYPE_CHECK_POD) 00404 min >> typeid(t); 00405 return read(min, t); 00406 } 00407 00408 template<> 00409 Marshal &operator>>(Marshal &min, double &t) { 00410 if (min.m_typeCheck & Marshal::TYPE_CHECK_POD) 00411 min >> typeid(t); 00412 return read(min, t); 00413 } 00414 00415 template<> 00416 Marshal &operator>>(Marshal &min, std::string &s) { 00417 if (min.m_typeCheck & Marshal::TYPE_CHECK_POD) 00418 min >> typeid(s); 00419 00420 size_t size = 0; 00421 min >> size; 00422 std::vector<char> c(size); 00423 00424 min.stream.read(&c[0], size); 00425 s.assign(&c[0], size); 00426 00427 return min; 00428 } 00429 00430 } // namespace stk