1 /*
2 Bacula(R) - The Network Backup Solution
3
4 Copyright (C) 2000-2020 Kern Sibbald
5
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
8
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
13
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
16
17 Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20
21 Serialisation Support Functions
22 John Walker
23 */
24
25
26 #include "bacula.h"
27 #include "serial.h"
28
29 /*
30
31 NOTE: The following functions should work on any
32 vaguely contemporary platform. Production
33 builds should use optimised macros (void
34 on platforms with network byte order and IEEE
35 floating point format as native.
36
37 */
38
39 /* serial_int16 -- Serialise a signed 16 bit integer. */
40
serial_int16(uint8_t ** const ptr,const int16_t v)41 void serial_int16(uint8_t * * const ptr, const int16_t v)
42 {
43 int16_t vo = htons(v);
44
45 memcpy(*ptr, &vo, sizeof vo);
46 *ptr += sizeof vo;
47 }
48
49 /* serial_uint16 -- Serialise an unsigned 16 bit integer. */
50
serial_uint16(uint8_t ** const ptr,const uint16_t v)51 void serial_uint16(uint8_t * * const ptr, const uint16_t v)
52 {
53 uint16_t vo = htons(v);
54
55 memcpy(*ptr, &vo, sizeof vo);
56 *ptr += sizeof vo;
57 }
58
59 /* serial_int32 -- Serialise a signed 32 bit integer. */
60
serial_int32(uint8_t ** const ptr,const int32_t v)61 void serial_int32(uint8_t * * const ptr, const int32_t v)
62 {
63 int32_t vo = htonl(v);
64
65 memcpy(*ptr, &vo, sizeof vo);
66 *ptr += sizeof vo;
67 }
68
69 /* serial_uint32 -- Serialise an unsigned 32 bit integer. */
70
serial_uint32(uint8_t ** const ptr,const uint32_t v)71 void serial_uint32(uint8_t * * const ptr, const uint32_t v)
72 {
73 uint32_t vo = htonl(v);
74
75 memcpy(*ptr, &vo, sizeof vo);
76 *ptr += sizeof vo;
77 }
78
79 /* serial_int64 -- Serialise a signed 64 bit integer. */
80
serial_int64(uint8_t ** const ptr,const int64_t v)81 void serial_int64(uint8_t * * const ptr, const int64_t v)
82 {
83 if (bigendian()) {
84 memcpy(*ptr, &v, sizeof(int64_t));
85 } else {
86 int i;
87 uint8_t rv[sizeof(int64_t)];
88 uint8_t *pv = (uint8_t *) &v;
89
90 for (i = 0; i < 8; i++) {
91 rv[i] = pv[7 - i];
92 }
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++) {
111 rv[i] = pv[7 - i];
112 }
113 memcpy(*ptr, &rv, sizeof(uint64_t));
114 }
115 *ptr += sizeof(uint64_t);
116 }
117
118
119 /* serial_btime -- Serialise an btime_t 64 bit integer. */
120
serial_btime(uint8_t ** const ptr,const btime_t v)121 void serial_btime(uint8_t * * const ptr, const btime_t v)
122 {
123 if (bigendian()) {
124 memcpy(*ptr, &v, sizeof(btime_t));
125 } else {
126 int i;
127 uint8_t rv[sizeof(btime_t)];
128 uint8_t *pv = (uint8_t *) &v;
129
130 for (i = 0; i < 8; i++) {
131 rv[i] = pv[7 - i];
132 }
133 memcpy(*ptr, &rv, sizeof(btime_t));
134 }
135 *ptr += sizeof(btime_t);
136 }
137
138
139
140 /* serial_float64 -- Serialise a 64 bit IEEE floating point number.
141 This code assumes that the host floating point
142 format is IEEE and that floating point quantities
143 are stored in IEEE format either LSB first or MSB
144 first. More creative host formats will require
145 additional transformations here. */
146
serial_float64(uint8_t ** const ptr,const float64_t v)147 void serial_float64(uint8_t * * const ptr, const float64_t v)
148 {
149 if (bigendian()) {
150 memcpy(*ptr, &v, sizeof(float64_t));
151 } else {
152 int i;
153 uint8_t rv[sizeof(float64_t)];
154 uint8_t *pv = (uint8_t *) &v;
155
156 for (i = 0; i < 8; i++) {
157 rv[i] = pv[7 - i];
158 }
159 memcpy(*ptr, &rv, sizeof(float64_t));
160 }
161 *ptr += sizeof(float64_t);
162 }
163
serial_string(uint8_t ** const ptr,const char * const str)164 void serial_string(uint8_t * * const ptr, const char * const str)
165 {
166 int i;
167 char *dest = (char *)*ptr;
168 char *src = (char *)str;
169 for (i=0; src[i] != 0; i++) {
170 dest[i] = src[i];
171 }
172 dest[i++] = 0; /* terminate output string */
173 *ptr += i; /* update pointer */
174 // Dmsg2(000, "ser src=%s dest=%s\n", src, dest);
175 }
176
177
178 /* unserial_int16 -- Unserialise a signed 16 bit integer. */
179
unserial_int16(uint8_t ** const ptr)180 int16_t unserial_int16(uint8_t * * const ptr)
181 {
182 int16_t vo;
183
184 memcpy(&vo, *ptr, sizeof vo);
185 *ptr += sizeof vo;
186 return ntohs(vo);
187 }
188
189 /* unserial_uint16 -- Unserialise an unsigned 16 bit integer. */
190
unserial_uint16(uint8_t ** const ptr)191 uint16_t unserial_uint16(uint8_t * * const ptr)
192 {
193 uint16_t vo;
194
195 memcpy(&vo, *ptr, sizeof vo);
196 *ptr += sizeof vo;
197 return ntohs(vo);
198 }
199
200 /* unserial_int32 -- Unserialise a signed 32 bit integer. */
201
unserial_int32(uint8_t ** const ptr)202 int32_t unserial_int32(uint8_t * * const ptr)
203 {
204 int32_t vo;
205
206 memcpy(&vo, *ptr, sizeof vo);
207 *ptr += sizeof vo;
208 return ntohl(vo);
209 }
210
211 /* unserial_uint32 -- Unserialise an unsigned 32 bit integer. */
212
unserial_uint32(uint8_t ** const ptr)213 uint32_t unserial_uint32(uint8_t * * const ptr)
214 {
215 uint32_t vo;
216
217 memcpy(&vo, *ptr, sizeof vo);
218 *ptr += sizeof vo;
219 return ntohl(vo);
220 }
221
222 /* unserial_int64 -- Unserialise a 64 bit integer. */
223
unserial_int64(uint8_t ** const ptr)224 int64_t unserial_int64(uint8_t * * const ptr)
225 {
226 int64_t v;
227
228 if (bigendian()) {
229 memcpy(&v, *ptr, sizeof(int64_t));
230 } else {
231 int i;
232 uint8_t rv[sizeof(int64_t)];
233 uint8_t *pv = (uint8_t *) &v;
234
235 memcpy(&v, *ptr, sizeof(uint64_t));
236 for (i = 0; i < 8; i++) {
237 rv[i] = pv[7 - i];
238 }
239 memcpy(&v, &rv, sizeof(uint64_t));
240 }
241 *ptr += sizeof(uint64_t);
242 return v;
243 }
244
245 /* unserial_uint64 -- Unserialise an unsigned 64 bit integer. */
246
unserial_uint64(uint8_t ** const ptr)247 uint64_t unserial_uint64(uint8_t * * const ptr)
248 {
249 uint64_t v;
250
251 if (bigendian()) {
252 memcpy(&v, *ptr, sizeof(uint64_t));
253 } else {
254 int i;
255 uint8_t rv[sizeof(uint64_t)];
256 uint8_t *pv = (uint8_t *) &v;
257
258 memcpy(&v, *ptr, sizeof(uint64_t));
259 for (i = 0; i < 8; i++) {
260 rv[i] = pv[7 - i];
261 }
262 memcpy(&v, &rv, sizeof(uint64_t));
263 }
264 *ptr += sizeof(uint64_t);
265 return v;
266 }
267
268 /* unserial_btime -- Unserialise a btime_t 64 bit integer. */
269
unserial_btime(uint8_t ** const ptr)270 btime_t unserial_btime(uint8_t * * const ptr)
271 {
272 btime_t v;
273
274 if (bigendian()) {
275 memcpy(&v, *ptr, sizeof(btime_t));
276 } else {
277 int i;
278 uint8_t rv[sizeof(btime_t)];
279 uint8_t *pv = (uint8_t *) &v;
280
281 memcpy(&v, *ptr, sizeof(btime_t));
282 for (i = 0; i < 8; i++) {
283 rv[i] = pv[7 - i];
284 }
285 memcpy(&v, &rv, sizeof(btime_t));
286 }
287 *ptr += sizeof(btime_t);
288 return v;
289 }
290
291
292
293 /* unserial_float64 -- Unserialise a 64 bit IEEE floating point number.
294 This code assumes that the host floating point
295 format is IEEE and that floating point quantities
296 are stored in IEEE format either LSB first or MSB
297 first. More creative host formats will require
298 additional transformations here. */
299
unserial_float64(uint8_t ** const ptr)300 float64_t unserial_float64(uint8_t * * const ptr)
301 {
302 float64_t v;
303
304 if (bigendian()) {
305 memcpy(&v, *ptr, sizeof(float64_t));
306 } else {
307 int i;
308 uint8_t rv[sizeof(float64_t)];
309 uint8_t *pv = (uint8_t *) &v;
310
311 memcpy(&v, *ptr, sizeof(float64_t));
312 for (i = 0; i < 8; i++) {
313 rv[i] = pv[7 - i];
314 }
315 memcpy(&v, &rv, sizeof(float64_t));
316 }
317 *ptr += sizeof(float64_t);
318 return v;
319 }
320
unserial_string(uint8_t ** const ptr,char * const str,int max)321 void unserial_string(uint8_t * * const ptr, char * const str, int max)
322 {
323 int i;
324 char *src = (char*)(*ptr);
325 char *dest = str;
326 for (i=0; i<max && src[i] != 0; i++) {
327 dest[i] = src[i];
328 }
329 dest[i++] = 0; /* terminate output string */
330 *ptr += i; /* update pointer */
331 // Dmsg2(000, "unser src=%s dest=%s\n", src, dest);
332 }
333