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