SST  14.0.0
StructuralSimulationToolkit
serializer.h
1 // Copyright 2009-2024 NTESS. Under the terms
2 // of Contract DE-NA0003525 with NTESS, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2024, NTESS
6 // All rights reserved.
7 //
8 // This file is part of the SST software package. For license
9 // information, see the LICENSE file in the top level directory of the
10 // distribution.
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 <cstdint>
20 #include <cstring>
21 #include <list>
22 #include <map>
23 #include <set>
24 #include <typeinfo>
25 #include <vector>
26 
27 namespace SST {
28 namespace Core {
29 namespace Serialization {
30 
31 /**
32  * This class is basically a wrapper for objects to declare the order in
33  * which their members should be ser/des
34  */
36 {
37 public:
38  typedef enum { SIZER, PACK, UNPACK } SERIALIZE_MODE;
39 
40 public:
41  serializer() : mode_(SIZER) // just sizing by default
42  {}
43 
44  pvt::ser_packer& packer() { return packer_; }
45 
46  pvt::ser_unpacker& unpacker() { return unpacker_; }
47 
48  pvt::ser_sizer& sizer() { return sizer_; }
49 
50  template <class T>
51  void size(T& t)
52  {
53  sizer_.size<T>(t);
54  }
55 
56  template <class T>
57  void pack(T& t)
58  {
59  packer_.pack<T>(t);
60  }
61 
62  template <class T>
63  void unpack(T& t)
64  {
65  unpacker_.unpack<T>(t);
66  }
67 
68  virtual ~serializer() {}
69 
70  SERIALIZE_MODE
71  mode() const { return mode_; }
72 
73  void set_mode(SERIALIZE_MODE mode) { mode_ = mode; }
74 
75  void reset()
76  {
77  sizer_.reset();
78  packer_.reset();
79  unpacker_.reset();
80  }
81 
82  template <typename T>
83  void primitive(T& t)
84  {
85  switch ( mode_ ) {
86  case SIZER:
87  sizer_.size(t);
88  break;
89  case PACK:
90  packer_.pack(t);
91  break;
92  case UNPACK:
93  unpacker_.unpack(t);
94  break;
95  }
96  }
97 
98  template <class T, int N>
99  void array(T arr[N])
100  {
101  switch ( mode_ ) {
102  case SIZER:
103  {
104  sizer_.add(sizeof(T) * N);
105  break;
106  }
107  case PACK:
108  {
109  char* charstr = packer_.next_str(N * sizeof(T));
110  ::memcpy(charstr, arr, N * sizeof(T));
111  break;
112  }
113  case UNPACK:
114  {
115  char* charstr = unpacker_.next_str(N * sizeof(T));
116  ::memcpy(arr, charstr, N * sizeof(T));
117  break;
118  }
119  }
120  }
121 
122  template <typename T, typename Int>
123  void binary(T*& buffer, Int& size)
124  {
125  switch ( mode_ ) {
126  case SIZER:
127  {
128  sizer_.add(sizeof(Int));
129  sizer_.add(size);
130  break;
131  }
132  case PACK:
133  {
134  if ( buffer ) {
135  packer_.pack(size);
136  packer_.pack_buffer(buffer, size * sizeof(T));
137  }
138  else {
139  Int nullsize = 0;
140  packer_.pack(nullsize);
141  }
142  break;
143  }
144  case UNPACK:
145  {
146  unpacker_.unpack(size);
147  if ( size != 0 ) { unpacker_.unpack_buffer(&buffer, size * sizeof(T)); }
148  else {
149  buffer = nullptr;
150  }
151  break;
152  }
153  }
154  }
155 
156  // For void*, we get sizeof(void), which errors.
157  // Create a wrapper that casts to char* and uses above
158  template <typename Int>
159  void binary(void*& buffer, Int& size)
160  {
161  char* tmp = (char*)buffer;
162  binary<char>(tmp, size);
163  buffer = tmp;
164  }
165 
166  void string(std::string& str);
167 
168  void start_packing(char* buffer, size_t size)
169  {
170  packer_.init(buffer, size);
171  mode_ = PACK;
172  ser_pointer_set.clear();
173  ser_pointer_map.clear();
174  }
175 
176  void start_sizing()
177  {
178  sizer_.reset();
179  mode_ = SIZER;
180  ser_pointer_set.clear();
181  ser_pointer_map.clear();
182  }
183 
184  void start_unpacking(char* buffer, size_t size)
185  {
186  unpacker_.init(buffer, size);
187  mode_ = UNPACK;
188  ser_pointer_set.clear();
189  ser_pointer_map.clear();
190  }
191 
192  size_t size() const
193  {
194  switch ( mode_ ) {
195  case SIZER:
196  return sizer_.size();
197  case PACK:
198  return packer_.size();
199  case UNPACK:
200  return unpacker_.size();
201  }
202  return 0;
203  }
204 
205  inline bool check_pointer_pack(uintptr_t ptr)
206  {
207  if ( ser_pointer_set.count(ptr) == 0 ) {
208  ser_pointer_set.insert(ptr);
209  return false;
210  }
211  return true;
212  }
213 
214  inline uintptr_t check_pointer_unpack(uintptr_t ptr)
215  {
216  auto it = ser_pointer_map.find(ptr);
217  if ( it != ser_pointer_map.end() ) { return it->second; }
218  // Keep a copy of the ptr in case we have a split report
219  split_key = ptr;
220  return 0;
221  }
222 
223  inline void report_new_pointer(uintptr_t real_ptr) { ser_pointer_map[split_key] = real_ptr; }
224 
225  inline void report_real_pointer(uintptr_t ptr, uintptr_t real_ptr) { ser_pointer_map[ptr] = real_ptr; }
226 
227  void enable_pointer_tracking(bool value = true) { enable_ptr_tracking_ = value; }
228 
229  inline bool is_pointer_tracking_enabled() { return enable_ptr_tracking_; }
230 
231 protected:
232  // only one of these is going to be valid for this serializer
233  // not very good class design, but a little more convenient
234  pvt::ser_packer packer_;
235  pvt::ser_unpacker unpacker_;
236  pvt::ser_sizer sizer_;
237  SERIALIZE_MODE mode_;
238  bool enable_ptr_tracking_ = false;
239 
240  std::set<uintptr_t> ser_pointer_set;
241  std::map<uintptr_t, uintptr_t> ser_pointer_map;
242  uintptr_t split_key;
243 };
244 
245 } // namespace Serialization
246 } // namespace Core
247 } // namespace SST
248 
249 #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:35
void unpack_buffer(void *buf, int size)
unpack_buffer
Definition: serializer.cc:25
Definition: action.cc:18
Definition: serialize_packer.h:24
void pack_buffer(void *buf, int size)
pack_buffer
Definition: serializer.cc:39
Definition: serialize_sizer.h:22
Definition: serialize_unpacker.h:22