My Project
Serializer.hpp
1 /*
2  Copyright 2020 Equinor ASA.
3 
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef OPM_SERIALIZER_HPP
21 #define OPM_SERIALIZER_HPP
22 
23 #include <cstring>
24 #include <string>
25 #include <unordered_map>
26 #include <vector>
27 
28 namespace Opm {
29 /*
30  This is a very basic serialization class used to support serialization of
31  small state objects from opm common. The main serialization code used in
32  opm/flow is initiated and controlled from the restart code, and therefor
33  slightly cumbersome to use for objects which should be serialized not as part
34  of the restart code.
35 */
36 
37 
38 class Serializer {
39 public:
40  Serializer() = default;
41  explicit Serializer(const std::vector<char>& buffer_arg) :
42  buffer(buffer_arg)
43  {}
44 
45 
46  template <typename T>
47  void put(const T& value) {
48  this->pack(std::addressof(value), sizeof(T));
49  }
50 
51  template <typename T>
52  void put(const T* ) {
53  throw std::logic_error("Serializer can not pack pointers");
54  }
55 
56  template <typename T>
57  T get() {
58  T value;
59  std::memcpy(&value, &this->buffer[this->read_pos], sizeof(T));
60  this->read_pos += sizeof(T);
61  return value;
62  }
63 
64  template<typename T>
65  void put_vector(const std::vector<T>& values) {
66  this->put(values.size());
67  this->pack(values.data(), values.size() * sizeof(T));
68  }
69 
70 
71 
72  template<typename T>
73  std::vector<T> get_vector() {
74  std::size_t size = this->get<std::size_t>();
75  std::vector<T> values(size);
76  for (std::size_t index=0; index < size; index++)
77  values[index] = this->get<T>();
78 
79  return values;
80  }
81 
82  template<typename K, typename T>
83  void put_map(const std::unordered_map<K,T>& values) {
84  this->put(values.size());
85  for (const auto& value_pair : values) {
86  this->put(value_pair.first);
87  this->put(value_pair.second);
88  }
89  }
90 
91  template<typename K, typename T>
92  std::unordered_map<K,T> get_map() {
93  std::unordered_map<K,T> values;
94  auto size = this->get<std::size_t>();
95  for (std::size_t index = 0; index < size; index++) {
96  auto key = this->get<K>();
97  auto value = this->get<T>();
98  values.insert( std::make_pair(key,value) );
99  }
100  return values;
101  }
102 
103 
104  std::vector<char> buffer;
105 private:
106  void pack(const void * ptr, std::size_t value_size) {
107  std::size_t write_pos = this->buffer.size();
108  std::size_t new_size = write_pos + value_size;
109  this->buffer.resize( new_size );
110  std::memcpy(&this->buffer[write_pos], ptr, value_size);
111  }
112 
113  std::size_t read_pos = 0;
114 };
115 
116 template <>
117 void inline Serializer::put(const std::string& value) {
118  this->put(value.size());
119  if (value.empty())
120  return;
121 
122  this->pack(value.c_str(), value.size());
123 }
124 
125 template<>
126 std::string inline Serializer::get<std::string>() {
127  std::string::size_type length = this->get<std::string::size_type>();
128  if (length == 0)
129  return std::string{};
130 
131  this->read_pos += length;
132  return {std::addressof(this->buffer[this->read_pos - length]), length};
133 }
134 
135 }
136 #endif
Definition: Serializer.hpp:38
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:29