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