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