1 /*
2 BAREOS® - Backup Archiving REcovery Open Sourced
3
4 Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
5 Copyright (C) 2013-2018 Bareos GmbH & Co. KG
6
7 This program is Free Software; you can redistribute it and/or
8 modify it under the terms of version three of the GNU Affero General Public
9 License as published by the Free Software Foundation and included
10 in the file LICENSE.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Affero General Public License for more details.
16
17 You should have received a copy of the GNU Affero General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA.
21 */
22 /*
23
24 Serialisation Support Functions
25 John Walker
26 */
27
28 #include "include/bareos.h"
29 #include "serial.h"
30
31 /*
32
33 NOTE: The following functions should work on any
34 vaguely contemporary platform. Production
35 builds should use optimised macros (void
36 on platforms with network byte order and IEEE
37 floating point format as native.
38
39 */
40
41 /* serial_int16 -- Serialise a signed 16 bit integer. */
42
serial_int16(uint8_t ** const ptr,const int16_t v)43 void serial_int16(uint8_t** const ptr, const int16_t v)
44 {
45 int16_t vo = htons(v);
46
47 memcpy(*ptr, &vo, sizeof vo);
48 *ptr += sizeof vo;
49 }
50
51 /* serial_uint16 -- Serialise an unsigned 16 bit integer. */
52
serial_uint16(uint8_t ** const ptr,const uint16_t v)53 void serial_uint16(uint8_t** const ptr, const uint16_t v)
54 {
55 uint16_t vo = htons(v);
56
57 memcpy(*ptr, &vo, sizeof vo);
58 *ptr += sizeof vo;
59 }
60
61 /* serial_int32 -- Serialise a signed 32 bit integer. */
62
serial_int32(uint8_t ** const ptr,const int32_t v)63 void serial_int32(uint8_t** const ptr, const int32_t v)
64 {
65 int32_t vo = htonl(v);
66
67 memcpy(*ptr, &vo, sizeof vo);
68 *ptr += sizeof vo;
69 }
70
71 /* serial_uint32 -- Serialise an unsigned 32 bit integer. */
72
serial_uint32(uint8_t ** const ptr,const uint32_t v)73 void serial_uint32(uint8_t** const ptr, const uint32_t v)
74 {
75 uint32_t vo = htonl(v);
76
77 memcpy(*ptr, &vo, sizeof vo);
78 *ptr += sizeof vo;
79 }
80
81 /* serial_int64 -- Serialise a signed 64 bit integer. */
82
serial_int64(uint8_t ** const ptr,const int64_t v)83 void serial_int64(uint8_t** const ptr, const int64_t v)
84 {
85 if (bigendian()) {
86 memcpy(*ptr, &v, sizeof(int64_t));
87 } else {
88 int i;
89 uint8_t rv[sizeof(int64_t)];
90 uint8_t* pv = (uint8_t*)&v;
91
92 for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; }
93 memcpy(*ptr, &rv, sizeof(int64_t));
94 }
95 *ptr += sizeof(int64_t);
96 }
97
98
99 /* serial_uint64 -- Serialise an unsigned 64 bit integer. */
100
serial_uint64(uint8_t ** const ptr,const uint64_t v)101 void serial_uint64(uint8_t** const ptr, const uint64_t v)
102 {
103 if (bigendian()) {
104 memcpy(*ptr, &v, sizeof(uint64_t));
105 } else {
106 int i;
107 uint8_t rv[sizeof(uint64_t)];
108 uint8_t* pv = (uint8_t*)&v;
109
110 for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; }
111 memcpy(*ptr, &rv, sizeof(uint64_t));
112 }
113 *ptr += sizeof(uint64_t);
114 }
115
116
117 /* SerialBtime -- Serialise an btime_t 64 bit integer. */
118
SerialBtime(uint8_t ** const ptr,const btime_t v)119 void SerialBtime(uint8_t** const ptr, const btime_t v)
120 {
121 if (bigendian()) {
122 memcpy(*ptr, &v, sizeof(btime_t));
123 } else {
124 int i;
125 uint8_t rv[sizeof(btime_t)];
126 uint8_t* pv = (uint8_t*)&v;
127
128 for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; }
129 memcpy(*ptr, &rv, sizeof(btime_t));
130 }
131 *ptr += sizeof(btime_t);
132 }
133
134
135 /* serial_float64 -- Serialise a 64 bit IEEE floating point number.
136 This code assumes that the host floating point
137 format is IEEE and that floating point quantities
138 are stored in IEEE format either LSB first or MSB
139 first. More creative host formats will require
140 additional transformations here. */
141
serial_float64(uint8_t ** const ptr,const float64_t v)142 void serial_float64(uint8_t** const ptr, const float64_t v)
143 {
144 if (bigendian()) {
145 memcpy(*ptr, &v, sizeof(float64_t));
146 } else {
147 int i;
148 uint8_t rv[sizeof(float64_t)];
149 uint8_t* pv = (uint8_t*)&v;
150
151 for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; }
152 memcpy(*ptr, &rv, sizeof(float64_t));
153 }
154 *ptr += sizeof(float64_t);
155 }
156
SerialString(uint8_t ** const ptr,const char * const str)157 void SerialString(uint8_t** const ptr, const char* const str)
158 {
159 int i;
160 char* dest = (char*)*ptr;
161 char* src = (char*)str;
162 for (i = 0; src[i] != 0; i++) { dest[i] = src[i]; }
163 dest[i++] = 0; /* Terminate output string */
164 *ptr += i; /* update pointer */
165 // Dmsg2(000, "ser src=%s dest=%s\n", src, dest);
166 }
167
168
169 /* unserial_int16 -- Unserialise a signed 16 bit integer. */
170
unserial_int16(uint8_t ** const ptr)171 int16_t unserial_int16(uint8_t** const ptr)
172 {
173 int16_t vo;
174
175 memcpy(&vo, *ptr, sizeof vo);
176 *ptr += sizeof vo;
177 return ntohs(vo);
178 }
179
180 /* unserial_uint16 -- Unserialise an unsigned 16 bit integer. */
181
unserial_uint16(uint8_t ** const ptr)182 uint16_t unserial_uint16(uint8_t** const ptr)
183 {
184 uint16_t vo;
185
186 memcpy(&vo, *ptr, sizeof vo);
187 *ptr += sizeof vo;
188 return ntohs(vo);
189 }
190
191 /* unserial_int32 -- Unserialise a signed 32 bit integer. */
192
unserial_int32(uint8_t ** const ptr)193 int32_t unserial_int32(uint8_t** const ptr)
194 {
195 int32_t vo;
196
197 memcpy(&vo, *ptr, sizeof vo);
198 *ptr += sizeof vo;
199 return ntohl(vo);
200 }
201
202 /* unserial_uint32 -- Unserialise an unsigned 32 bit integer. */
203
unserial_uint32(uint8_t ** const ptr)204 uint32_t unserial_uint32(uint8_t** const ptr)
205 {
206 uint32_t vo;
207
208 memcpy(&vo, *ptr, sizeof vo);
209 *ptr += sizeof vo;
210 return ntohl(vo);
211 }
212
213 /* unserial_uint64 -- Unserialise an unsigned 64 bit integer. */
214
unserial_uint64(uint8_t ** const ptr)215 uint64_t unserial_uint64(uint8_t** const ptr)
216 {
217 uint64_t v;
218
219 if (bigendian()) {
220 memcpy(&v, *ptr, sizeof(uint64_t));
221 } else {
222 int i;
223 uint8_t rv[sizeof(uint64_t)];
224 uint8_t* pv = (uint8_t*)&v;
225
226 memcpy(&v, *ptr, sizeof(uint64_t));
227 for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; }
228 memcpy(&v, &rv, sizeof(uint64_t));
229 }
230 *ptr += sizeof(uint64_t);
231 return v;
232 }
233
234 /* UnserialBtime -- Unserialise a btime_t 64 bit integer. */
235
UnserialBtime(uint8_t ** const ptr)236 btime_t UnserialBtime(uint8_t** const ptr)
237 {
238 btime_t v;
239
240 if (bigendian()) {
241 memcpy(&v, *ptr, sizeof(btime_t));
242 } else {
243 int i;
244 uint8_t rv[sizeof(btime_t)];
245 uint8_t* pv = (uint8_t*)&v;
246
247 memcpy(&v, *ptr, sizeof(btime_t));
248 for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; }
249 memcpy(&v, &rv, sizeof(btime_t));
250 }
251 *ptr += sizeof(btime_t);
252 return v;
253 }
254
255
256 /* unserial_float64 -- Unserialise a 64 bit IEEE floating point number.
257 This code assumes that the host floating point
258 format is IEEE and that floating point quantities
259 are stored in IEEE format either LSB first or MSB
260 first. More creative host formats will require
261 additional transformations here. */
262
unserial_float64(uint8_t ** const ptr)263 float64_t unserial_float64(uint8_t** const ptr)
264 {
265 float64_t v;
266
267 if (bigendian()) {
268 memcpy(&v, *ptr, sizeof(float64_t));
269 } else {
270 int i;
271 uint8_t rv[sizeof(float64_t)];
272 uint8_t* pv = (uint8_t*)&v;
273
274 memcpy(&v, *ptr, sizeof(float64_t));
275 for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; }
276 memcpy(&v, &rv, sizeof(float64_t));
277 }
278 *ptr += sizeof(float64_t);
279 return v;
280 }
281
UnserialString(uint8_t ** const ptr,char * const str,int max)282 void UnserialString(uint8_t** const ptr, char* const str, int max)
283 {
284 int i;
285 char* src = (char*)(*ptr);
286 char* dest = str;
287 for (i = 0; i < max && src[i] != 0; i++) { dest[i] = src[i]; }
288 dest[i++] = 0; /* Terminate output string */
289 *ptr += i; /* update pointer */
290 // Dmsg2(000, "unser src=%s dest=%s\n", src, dest);
291 }
292