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