Apply clang-format to source tree
[alexxy/gromacs.git] / src / gromacs / utility / inmemoryserializer.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 #include "gmxpre.h"
36
37 #include "inmemoryserializer.h"
38
39 #include <algorithm>
40 #include <vector>
41
42 #include "gromacs/utility/gmxassert.h"
43
44 namespace gmx
45 {
46
47 namespace
48 {
49
50 template<typename T>
51 class CharBuffer
52 {
53 public:
54     static const size_t ValueSize = sizeof(T);
55
56     explicit CharBuffer(T value) { u.v = value; }
57     explicit CharBuffer(const char buffer[]) { std::copy(buffer, buffer + ValueSize, u.c); }
58
59     T value() const { return u.v; }
60
61     void appendTo(std::vector<char>* buffer)
62     {
63         buffer->insert(buffer->end(), u.c, u.c + ValueSize);
64     }
65
66 private:
67     union {
68         char c[ValueSize];
69         T    v;
70     } u;
71 };
72
73 } // namespace
74
75 /********************************************************************
76  * InMemorySerializer
77  */
78
79 class InMemorySerializer::Impl
80 {
81 public:
82     template<typename T>
83     void doValue(T value)
84     {
85         CharBuffer<T>(value).appendTo(&buffer_);
86     }
87     void doString(const std::string& value)
88     {
89         doValue<uint64_t>(value.size());
90         buffer_.insert(buffer_.end(), value.begin(), value.end());
91     }
92
93     std::vector<char> buffer_;
94 };
95
96 InMemorySerializer::InMemorySerializer() : impl_(new Impl) {}
97
98 InMemorySerializer::~InMemorySerializer() {}
99
100 std::vector<char> InMemorySerializer::finishAndGetBuffer()
101 {
102     return std::move(impl_->buffer_);
103 }
104
105 void InMemorySerializer::doBool(bool* value)
106 {
107     impl_->doValue(*value);
108 }
109
110 void InMemorySerializer::doUChar(unsigned char* value)
111 {
112     impl_->doValue(*value);
113 }
114
115 void InMemorySerializer::doChar(char* value)
116 {
117     impl_->doValue(*value);
118 }
119
120 void InMemorySerializer::doUShort(unsigned short* value)
121 {
122     impl_->doValue(*value);
123 }
124
125 void InMemorySerializer::doInt(int* value)
126 {
127     impl_->doValue(*value);
128 }
129
130 void InMemorySerializer::doInt32(int32_t* value)
131 {
132     impl_->doValue(*value);
133 }
134
135 void InMemorySerializer::doInt64(int64_t* value)
136 {
137     impl_->doValue(*value);
138 }
139
140 void InMemorySerializer::doFloat(float* value)
141 {
142     impl_->doValue(*value);
143 }
144
145 void InMemorySerializer::doDouble(double* value)
146 {
147     impl_->doValue(*value);
148 }
149
150 void InMemorySerializer::doReal(real* value)
151 {
152     impl_->doValue(*value);
153 }
154
155 void InMemorySerializer::doRvec(rvec* value)
156 {
157     for (int d = 0; d < DIM; d++)
158     {
159         doReal(&(*value)[d]);
160     }
161 }
162
163 void InMemorySerializer::doIvec(ivec* value)
164 {
165     for (int d = 0; d < DIM; d++)
166     {
167         doInt(&(*value)[d]);
168     }
169 }
170
171 void InMemorySerializer::doString(std::string* value)
172 {
173     impl_->doString(*value);
174 }
175
176 /********************************************************************
177  * InMemoryDeserializer
178  */
179
180 class InMemoryDeserializer::Impl
181 {
182 public:
183     explicit Impl(ArrayRef<const char> buffer, bool sourceIsDouble) :
184         buffer_(buffer),
185         sourceIsDouble_(sourceIsDouble),
186         pos_(0)
187     {
188     }
189
190     template<typename T>
191     void doValue(T* value)
192     {
193         *value = CharBuffer<T>(&buffer_[pos_]).value();
194         pos_ += CharBuffer<T>::ValueSize;
195     }
196     void doString(std::string* value)
197     {
198         uint64_t size;
199         doValue<uint64_t>(&size);
200         *value = std::string(&buffer_[pos_], size);
201         pos_ += size;
202     }
203
204     ArrayRef<const char> buffer_;
205     bool                 sourceIsDouble_;
206     size_t               pos_;
207 };
208
209 InMemoryDeserializer::InMemoryDeserializer(ArrayRef<const char> buffer, bool sourceIsDouble) :
210     impl_(new Impl(buffer, sourceIsDouble))
211 {
212 }
213
214 InMemoryDeserializer::~InMemoryDeserializer() {}
215
216 bool InMemoryDeserializer::sourceIsDouble() const
217 {
218     return impl_->sourceIsDouble_;
219 }
220
221 void InMemoryDeserializer::doBool(bool* value)
222 {
223     impl_->doValue(value);
224 }
225
226 void InMemoryDeserializer::doUChar(unsigned char* value)
227 {
228     impl_->doValue(value);
229 }
230
231 void InMemoryDeserializer::doChar(char* value)
232 {
233     impl_->doValue(value);
234 }
235
236 void InMemoryDeserializer::doUShort(unsigned short* value)
237 {
238     impl_->doValue(value);
239 }
240
241 void InMemoryDeserializer::doInt(int* value)
242 {
243     impl_->doValue(value);
244 }
245
246 void InMemoryDeserializer::doInt32(int32_t* value)
247 {
248     impl_->doValue(value);
249 }
250
251 void InMemoryDeserializer::doInt64(int64_t* value)
252 {
253     impl_->doValue(value);
254 }
255
256 void InMemoryDeserializer::doFloat(float* value)
257 {
258     impl_->doValue(value);
259 }
260
261 void InMemoryDeserializer::doDouble(double* value)
262 {
263     impl_->doValue(value);
264 }
265
266 void InMemoryDeserializer::doReal(real* value)
267 {
268     if (sourceIsDouble())
269     {
270         double temp = 0.0;
271         doDouble(&temp);
272         *value = temp;
273     }
274     else
275     {
276         float temp = 0.0;
277         doFloat(&temp);
278         *value = temp;
279     }
280 }
281
282 void InMemoryDeserializer::doRvec(rvec* value)
283 {
284     for (int d = 0; d < DIM; d++)
285     {
286         doReal(&(*value)[d]);
287     }
288 }
289
290 void InMemoryDeserializer::doIvec(ivec* value)
291 {
292     for (int d = 0; d < DIM; d++)
293     {
294         doInt(&(*value)[d]);
295     }
296 }
297
298 void InMemoryDeserializer::doString(std::string* value)
299 {
300     impl_->doString(value);
301 }
302
303 } // namespace gmx