Sierra Toolkit  Version of the Day
Marshal.cpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010 Sandia Corporation. */
3 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
4 /* license for use of this work by or on behalf of the U.S. Government. */
5 /* Export of this program may require a license from the */
6 /* United States Government. */
7 /*------------------------------------------------------------------------*/
8 
9 #include <stdexcept>
10 #include <map>
11 #include <cstring>
12 
13 #include <stk_util/util/Marshal.hpp>
14 #include <iostream>
15 
16 namespace stk_classic {
17 
18 namespace {
19 
20 typedef std::map<uint32_t, std::string> TypeNameMap;
21 
22 bool s_crcInitialized = false;
23 uint32_t s_crcTable[256];
24 TypeNameMap s_typeNameMap;
25 
26 uint32_t
27 crc32_reflect(
28  uint32_t seed,
29  const char c)
30 {
31  uint32_t value = 0;
32 
33  // Swap bit 0 for bit 7, bit 1 For bit 6, etc....
34  for(int i = 1; i < (c + 1); i++) {
35  if (seed & 1)
36  value |= (1 << (c - i));
37  seed >>= 1;
38  }
39 
40  return value;
41 }
42 
43 
44 void
45 crc32_initialize()
46 {
47  s_crcInitialized = true;
48 
49  //0x04C11DB7 is the official polynomial used by PKZip, WinZip and Ethernet.
50  uint32_t polynomial = 0x04C11DB7;
51 
52  std::fill(s_crcTable, s_crcTable + 256, 0);
53 
54  // 256 values representing ASCII character codes.
55  for (int i = 0; i <= 0xFF; i++) {
56  s_crcTable[i] = crc32_reflect(i, 8) << 24;
57 
58  for (int j = 0; j < 8; j++)
59  s_crcTable[i] = (s_crcTable[i] << 1) ^ ((s_crcTable[i] & (1u << 31)) ? polynomial : 0);
60 
61  s_crcTable[i] = crc32_reflect(s_crcTable[i], 32);
62  }
63 }
64 
65 
66 void
67 crc32_part(
68  uint32_t & crc,
69  const unsigned char * s,
70  unsigned l)
71 {
72  while (l--)
73  crc = (crc >> 8)^s_crcTable[(crc & 0xFF)^*s++];
74 }
75 
76 
77 uint32_t
78 crc32(
79  const unsigned char * s,
80  unsigned l)
81 {
82  uint32_t crc = 0xffffffff;
83  crc32_part(crc, s, l);
84  return crc ^ 0xffffffff;
85 }
86 
87 
88 void
89 crc32_write(
90  std::stringstream & os,
91  const std::type_info & typeinfo)
92 {
93  if (!s_crcInitialized)
94  crc32_initialize();
95 
96  const char *name = typeinfo.name();
97  unsigned length = std::strlen(name);
98 
99  uint32_t crc = crc32((const unsigned char *) name, length);
100 
101  TypeNameMap::iterator it = s_typeNameMap.find(crc);
102  if (it == s_typeNameMap.end())
103  s_typeNameMap.insert(std::make_pair(crc, std::string(name)));
104 
105  os.write((const char *) &crc, sizeof(uint32_t));
106 }
107 
108 
109 void
110 crc32_check(
111  std::stringstream & is,
112  const std::type_info & typeinfo)
113 {
114  if (!s_crcInitialized)
115  crc32_initialize();
116 
117  const char *name = typeinfo.name();
118  unsigned length = std::strlen(name);
119 
120  uint32_t crc_check = crc32((const unsigned char *) name, length);
121  uint32_t crc = 0;
122 
123  {
124  TypeNameMap::iterator it = s_typeNameMap.find(crc_check);
125  if (it == s_typeNameMap.end())
126  s_typeNameMap.insert(std::make_pair(crc_check, std::string(name)));
127  }
128 
129  is.read((char *) &crc, sizeof(uint32_t));
130 
131  if (crc_check != crc) {
132  std::ostringstream ss;
133  ss << "Marshaller encountered type ";
134  TypeNameMap::const_iterator it = s_typeNameMap.find(crc);
135  if (it == s_typeNameMap.end())
136  ss << "code " << std::hex << crc;
137  else
138  ss << (*it).second;
139 
140  ss << " when expecting type ";
141  it = s_typeNameMap.find(crc_check);
142  if (it == s_typeNameMap.end())
143  ss << "code " << std::hex << crc_check;
144  else
145  ss << (*it).second;
146 
147  throw std::runtime_error(ss.str());
148  }
149 }
150 
151 } // namespace <empty>
152 
154  unsigned type_check)
155  : stream(std::ios_base::out),
156  m_typeCheck(TYPE_CHECK_NONE)
157 {
158  (*this) << type_check;
159  m_typeCheck = type_check;
160 }
161 
162 
164  const std::string & s)
165  : stream(s, std::ios_base::in),
166  m_typeCheck(TYPE_CHECK_NONE)
167 {
168  (*this) >> m_typeCheck;
169 }
170 
171 
172 std::string
174 {
175  return stream.str();
176 }
177 
178 
179 size_t
181 {
182  return stream.str().size();
183 }
184 
185 
186 Marshal::operator void * () const
187 {
188  return static_cast<void *>(const_cast<std::stringstream*>(&stream));
189 }
190 
191 
192 void
194  const char * address,
195  size_t byte_count)
196 {
197  stream.write(address, byte_count);
198 }
199 
200 
201 void
203  char * address,
204  size_t byte_count)
205 {
206  stream.read(address, byte_count);
207 }
208 
209 
210 template<>
211 Marshal &operator<<(Marshal &mout, const std::type_info &t) {
212  crc32_write(mout.stream, t);
213  return mout;
214 }
215 
216 template<>
217 Marshal &operator>>(Marshal &min, const std::type_info &t) {
218  crc32_check(min.stream, t);
219  return min;
220 }
221 
222 template<>
223 Marshal &operator<<(Marshal &mout, const signed char &t) {
224  if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD)
225  mout << typeid(t);
226  return write(mout, t);
227 }
228 
229 template<>
230 Marshal &operator<<(Marshal &mout, const unsigned char &t) {
231  if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD)
232  mout << typeid(t);
233  return write(mout, t);
234 }
235 
236 template<>
237 Marshal &operator<<(Marshal &mout, const char &t) {
238  if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD)
239  mout << typeid(t);
240  return write(mout, t);
241 }
242 
243 template<>
244 Marshal &operator<<(Marshal &mout, const short &t) {
245  if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD)
246  mout << typeid(t);
247  return write(mout, t);
248 }
249 
250 template<>
251 Marshal &operator<<(Marshal &mout, const unsigned short &t) {
252  if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD)
253  mout << typeid(t);
254  return write(mout, t);
255 }
256 
257 template<>
258 Marshal &operator<<(Marshal &mout, const int &t) {
259  if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD)
260  mout << typeid(t);
261  return write(mout, t);
262 }
263 
264 template<>
265 Marshal &operator<<(Marshal &mout, const unsigned int &t) {
266  if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD)
267  mout << typeid(t);
268  return write(mout, t);
269 }
270 
271 template<>
272 Marshal &operator<<(Marshal &mout, const long &t) {
273  if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD)
274  mout << typeid(t);
275  return write(mout, t);
276 }
277 
278 template<>
279 Marshal &operator<<(Marshal &mout, const unsigned long &t) {
280  if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD)
281  mout << typeid(t);
282  return write(mout, t);
283 }
284 
285 template<>
286 Marshal &operator<<(Marshal &mout, const long long &t) {
287  if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD)
288  mout << typeid(t);
289  return write(mout, t);
290 }
291 
292 template<>
293 Marshal &operator<<(Marshal &mout, const unsigned long long &t) {
294  if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD)
295  mout << typeid(t);
296  return write(mout, t);
297 }
298 
299 template<>
300 Marshal &operator<<(Marshal &mout, const float &t) {
301  if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD)
302  mout << typeid(t);
303  return write(mout, t);
304 }
305 
306 template<>
307 Marshal &operator<<(Marshal &mout, const double &t) {
308  if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD)
309  mout << typeid(t);
310  return write(mout, t);
311 }
312 
313 template<>
314 Marshal &operator<<(Marshal &mout, const std::string &s) {
315  if (mout.m_typeCheck & Marshal::TYPE_CHECK_POD)
316  mout << typeid(s);
317 
318  size_t ul = s.size();
319  mout << ul;
320  mout.stream.write(s.data(), s.size());
321  return mout;
322 }
323 
324 
325 template<>
326 Marshal &operator>>(Marshal &min, signed char &t) {
327  if (min.m_typeCheck & Marshal::TYPE_CHECK_POD)
328  min >> typeid(t);
329  return read(min, t);
330 }
331 
332 template<>
333 Marshal &operator>>(Marshal &min, unsigned char &t) {
334  if (min.m_typeCheck & Marshal::TYPE_CHECK_POD)
335  min >> typeid(t);
336  return read(min, t);
337 }
338 
339 template<>
340 Marshal &operator>>(Marshal &min, char &t) {
341  if (min.m_typeCheck & Marshal::TYPE_CHECK_POD)
342  min >> typeid(t);
343  return read(min, t);
344 }
345 
346 template<>
347 Marshal &operator>>(Marshal &min, short &t) {
348  if (min.m_typeCheck & Marshal::TYPE_CHECK_POD)
349  min >> typeid(t);
350  return read(min, t);
351 }
352 
353 template<>
354 Marshal &operator>>(Marshal &min, unsigned short &t) {
355  if (min.m_typeCheck & Marshal::TYPE_CHECK_POD)
356  min >> typeid(t);
357  return read(min, t);
358 }
359 
360 template<>
361 Marshal &operator>>(Marshal &min, int &t) {
362  if (min.m_typeCheck & Marshal::TYPE_CHECK_POD)
363  min >> typeid(t);
364  return read(min, t);
365 }
366 
367 template<>
368 Marshal &operator>>(Marshal &min, unsigned int &t) {
369  if (min.m_typeCheck & Marshal::TYPE_CHECK_POD)
370  min >> typeid(t);
371  return read(min, t);
372 }
373 
374 template<>
375 Marshal &operator>>(Marshal &min, long &t) {
376  if (min.m_typeCheck & Marshal::TYPE_CHECK_POD)
377  min >> typeid(t);
378  return read(min, t);
379 }
380 
381 template<>
382 Marshal &operator>>(Marshal &min, unsigned long &t) {
383  if (min.m_typeCheck & Marshal::TYPE_CHECK_POD)
384  min >> typeid(t);
385  return read(min, t);
386 }
387 
388 template<>
389 Marshal &operator>>(Marshal &min, long long &t) {
390  if (min.m_typeCheck & Marshal::TYPE_CHECK_POD)
391  min >> typeid(t);
392  return read(min, t);
393 }
394 
395 template<>
396 Marshal &operator>>(Marshal &min, unsigned long long &t) {
397  if (min.m_typeCheck & Marshal::TYPE_CHECK_POD)
398  min >> typeid(t);
399  return read(min, t);
400 }
401 
402 template<>
403 Marshal &operator>>(Marshal &min, float &t) {
404  if (min.m_typeCheck & Marshal::TYPE_CHECK_POD)
405  min >> typeid(t);
406  return read(min, t);
407 }
408 
409 template<>
410 Marshal &operator>>(Marshal &min, double &t) {
411  if (min.m_typeCheck & Marshal::TYPE_CHECK_POD)
412  min >> typeid(t);
413  return read(min, t);
414 }
415 
416 template<>
417 Marshal &operator>>(Marshal &min, std::string &s) {
418  if (min.m_typeCheck & Marshal::TYPE_CHECK_POD)
419  min >> typeid(s);
420 
421  size_t size = 0;
422  min >> size;
423  std::vector<char> c(size);
424 
425  min.stream.read(&c[0], size);
426  s.assign(&c[0], size);
427 
428  return min;
429 }
430 
431 } // namespace stk_classic
size_t size() const
Member function size returns the byte count of the string of packed bytes creates by put-to operation...
Definition: Marshal.cpp:180
Marshal(unsigned type_check=TYPE_CHECK_NONE)
Definition: Marshal.cpp:153
void write(const char *address, size_t byte_count)
Member function write writer bytes to the packed byte stream.
Definition: Marshal.cpp:193
Struct Marshal is a data packer for sending and receiving parallel messages. The data put-to (<<) is ...
Definition: Marshal.hpp:49
std::ostream & operator<<(std::ostream &s, const Bucket &k)
Print the part names for which this bucket is a subset.
Definition: Bucket.cpp:239
std::string str() const
Member function str returns the string of packed bytes created by put-to operations to the stream...
Definition: Marshal.cpp:173
std::stringstream stream
Packed byte stream to put-to or get-from.
Definition: Marshal.hpp:126
unsigned m_typeCheck
Type checking to activate.
Definition: Marshal.hpp:127
void read(char *address, size_t byte_count)
Member function read reads bytes from the packed byte stream.
Definition: Marshal.cpp:202
Sierra Toolkit.