SST  11.1.0
StructuralSimulationToolkit
serializer.h
1 /*
2  * This file is part of SST/macroscale:
3  * The macroscale architecture simulator from the SST suite.
4  * Copyright (c) 2009-2021 NTESS.
5  * This software is distributed under the BSD License.
6  * Under the terms of Contract DE-NA0003525 with NTESS,
7  * the U.S. Government retains certain rights in this software.
8  * For more information, see the LICENSE file in the top
9  * SST/macroscale directory.
10  */
11 
12 #ifndef SST_CORE_SERIALIZATION_SERIALIZER_H
13 #define SST_CORE_SERIALIZATION_SERIALIZER_H
14 
15 #include "sst/core/serialization/serialize_packer.h"
16 #include "sst/core/serialization/serialize_sizer.h"
17 #include "sst/core/serialization/serialize_unpacker.h"
18 
19 #include <cstring>
20 #include <list>
21 #include <map>
22 #include <set>
23 #include <typeinfo>
24 #include <vector>
25 
26 namespace SST {
27 namespace Core {
28 namespace Serialization {
29 
30 /**
31  * This class is basically a wrapper for objects to declare the order in
32  * which their members should be ser/des
33  */
35 {
36 public:
37  typedef enum { SIZER, PACK, UNPACK } SERIALIZE_MODE;
38 
39 public:
40  serializer() : mode_(SIZER) // just sizing by default
41  {}
42 
43  pvt::ser_packer& packer() { return packer_; }
44 
45  pvt::ser_unpacker& unpacker() { return unpacker_; }
46 
47  pvt::ser_sizer& sizer() { return sizer_; }
48 
49  template <class T>
50  void size(T& t)
51  {
52  sizer_.size<T>(t);
53  }
54 
55  template <class T>
56  void pack(T& t)
57  {
58  packer_.pack<T>(t);
59  }
60 
61  template <class T>
62  void unpack(T& t)
63  {
64  unpacker_.unpack<T>(t);
65  }
66 
67  virtual ~serializer() {}
68 
69  SERIALIZE_MODE
70  mode() const { return mode_; }
71 
72  void set_mode(SERIALIZE_MODE mode) { mode_ = mode; }
73 
74  void reset()
75  {
76  sizer_.reset();
77  packer_.reset();
78  unpacker_.reset();
79  }
80 
81  template <typename T>
82  void primitive(T& t)
83  {
84  switch ( mode_ ) {
85  case SIZER:
86  sizer_.size(t);
87  break;
88  case PACK:
89  packer_.pack(t);
90  break;
91  case UNPACK:
92  unpacker_.unpack(t);
93  break;
94  }
95  }
96 
97  template <class T, int N>
98  void array(T arr[N])
99  {
100  switch ( mode_ ) {
101  case SIZER:
102  {
103  sizer_.add(sizeof(T) * N);
104  break;
105  }
106  case PACK:
107  {
108  char* charstr = packer_.next_str(N * sizeof(T));
109  ::memcpy(charstr, arr, N * sizeof(T));
110  break;
111  }
112  case UNPACK:
113  {
114  char* charstr = unpacker_.next_str(N * sizeof(T));
115  ::memcpy(arr, charstr, N * sizeof(T));
116  break;
117  }
118  }
119  }
120 
121  template <typename T, typename Int>
122  void binary(T*& buffer, Int& size)
123  {
124  switch ( mode_ ) {
125  case SIZER:
126  {
127  sizer_.add(sizeof(Int));
128  sizer_.add(size);
129  break;
130  }
131  case PACK:
132  {
133  if ( buffer ) {
134  packer_.pack(size);
135  packer_.pack_buffer(buffer, size * sizeof(T));
136  }
137  else {
138  Int nullsize = 0;
139  packer_.pack(nullsize);
140  }
141  break;
142  }
143  case UNPACK:
144  {
145  unpacker_.unpack(size);
146  if ( size != 0 ) { unpacker_.unpack_buffer(&buffer, size * sizeof(T)); }
147  else {
148  buffer = nullptr;
149  }
150  break;
151  }
152  }
153  }
154 
155  // For void*, we get sizeof(void), which errors.
156  // Create a wrapper that casts to char* and uses above
157  template <typename Int>
158  void binary(void*& buffer, Int& size)
159  {
160  char* tmp = (char*)buffer;
161  binary<char>(tmp, size);
162  buffer = tmp;
163  }
164 
165  void string(std::string& str);
166 
167  void start_packing(char* buffer, size_t size)
168  {
169  packer_.init(buffer, size);
170  mode_ = PACK;
171  }
172 
173  void start_sizing()
174  {
175  sizer_.reset();
176  mode_ = SIZER;
177  }
178 
179  void start_unpacking(char* buffer, size_t size)
180  {
181  unpacker_.init(buffer, size);
182  mode_ = UNPACK;
183  }
184 
185  size_t size() const
186  {
187  switch ( mode_ ) {
188  case SIZER:
189  return sizer_.size();
190  case PACK:
191  return packer_.size();
192  case UNPACK:
193  return unpacker_.size();
194  }
195  return 0;
196  }
197 
198 protected:
199  // only one of these is going to be valid for this spkt_serializer
200  // not very good class design, but a little more convenient
201  pvt::ser_packer packer_;
202  pvt::ser_unpacker unpacker_;
203  pvt::ser_sizer sizer_;
204  SERIALIZE_MODE mode_;
205 };
206 
207 } // namespace Serialization
208 } // namespace Core
209 } // namespace SST
210 
211 #endif // SST_CORE_SERIALIZATION_SERIALIZER_H
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:34
void unpack_buffer(void *buf, int size)
unpack_buffer
Definition: serializer.cc:24
Definition: serialize_packer.h:24
void pack_buffer(void *buf, int size)
pack_buffer
Definition: serializer.cc:38
Definition: serialize_sizer.h:22
Definition: serialize_unpacker.h:22