root/trunk/src/proto/endecode-funcs.h @ 4617

Revision 4617, 16.6 KB (checked in by robl, 8 years ago)

[pcarns]: add protocol versioning to PVFS2. Major version changes are
incompatible up or down. New clients can't talk to old servers, but new
servers can talk to old clients.

Line 
1/*
2 * (C) 2003 Pete Wyckoff, Ohio Supercomputer Center <pw@osc.edu>
3 *
4 * See COPYING in top-level directory.
5 *
6 * Defines for macros related to wire encoding and decoding.  Only included
7 * by include/pvfs2-encode-stubs.h by core encoding users.
8 */
9/* NOTE: if you make any changes to the code contained in this file, please
10 * update the PVFS2_PROTO_VERSION in pvfs2-req-proto.h accordingly
11 */
12#ifndef __SRC_PROTO_ENDECODE_FUNCS_H
13#define __SRC_PROTO_ENDECODE_FUNCS_H
14
15#include "src/io/bmi/bmi-byteswap.h"
16
17/*
18 * NOTE - Every macro defined here needs to have a stub defined in
19 * include/pvfs2-encode-stubs.h
20 */
21
22/*
23 * Generic macros to define encoding near target structure declarations.
24 */
25
26/* basic types */
27#define encode_uint64_t(pptr,x) do { \
28    *(u_int64_t*) *(pptr) = htobmi64(*(x)); \
29    *(pptr) += 8; \
30} while (0)
31#define decode_uint64_t(pptr,x) do { \
32    *(x) = bmitoh64(*(u_int64_t*) *(pptr)); \
33    *(pptr) += 8; \
34} while (0)
35
36#define encode_int64_t(pptr,x) do { \
37    *(int64_t*) *(pptr) = htobmi64(*(x)); \
38    *(pptr) += 8; \
39} while (0)
40#define decode_int64_t(pptr,x) do { \
41    *(x) = bmitoh64(*(int64_t*) *(pptr)); \
42    *(pptr) += 8; \
43} while (0)
44
45#define encode_uint32_t(pptr,x) do { \
46    *(u_int32_t*) *(pptr) = htobmi32(*(x)); \
47    *(pptr) += 4; \
48} while (0)
49#define decode_uint32_t(pptr,x) do { \
50    *(x) = bmitoh32(*(u_int32_t*) *(pptr)); \
51    *(pptr) += 4; \
52} while (0)
53
54#define encode_int32_t(pptr,x) do { \
55    *(int32_t*) *(pptr) = htobmi32(*(x)); \
56    *(pptr) += 4; \
57} while (0)
58#define decode_int32_t(pptr,x) do { \
59    *(x) = bmitoh32(*(int32_t*) *(pptr)); \
60    *(pptr) += 4; \
61} while (0)
62
63/* skip 4 bytes */
64#define encode_skip4(pptr,x) do { \
65    *(pptr) += 4; \
66} while (0)
67#define decode_skip4(pptr,x) do { \
68    *(pptr) += 4; \
69} while (0)
70
71/* strings; decoding just points into existing character data */
72#define encode_string(pptr,pbuf) do { \
73    u_int32_t len = strlen(*pbuf); \
74    *(u_int32_t *) *(pptr) = htobmi32(len); \
75    memcpy(*(pptr)+4, *pbuf, len+1); \
76    *(pptr) += roundup8(4 + len + 1); \
77} while (0)
78#define decode_string(pptr,pbuf) do { \
79    u_int32_t len = bmitoh32(*(u_int32_t *) *(pptr)); \
80    *pbuf = *(pptr) + 4; \
81    *(pptr) += roundup8(4 + len + 1); \
82} while (0)
83
84/* odd variation, space exists in some structure, must copy-in string */
85#define encode_here_string(pptr,pbuf) encode_string(pptr,pbuf)
86#define decode_here_string(pptr,pbuf) do { \
87    u_int32_t len = bmitoh32(*(u_int32_t *) *(pptr)); \
88    memcpy(pbuf, *(pptr) + 4, len + 1); \
89    *(pptr) += roundup8(4 + len + 1); \
90} while (0)
91
92/* keyvals; a lot like strings; decoding points existing character data */
93/* BTW we are skipping the read_sz field - keep that in mind */
94#define encode_PVFS_ds_keyval(pptr,pbuf) do { \
95    u_int32_t len = ((PVFS_ds_keyval *)pbuf)->buffer_sz; \
96    *(u_int32_t *) *(pptr) = htobmi32(len); \
97    memcpy(*(pptr)+4, ((PVFS_ds_keyval *)pbuf)->buffer, len); \
98    *(pptr) += roundup8(4 + len); \
99} while (0)
100#define decode_PVFS_ds_keyval(pptr,pbuf) do { \
101    u_int32_t len = bmitoh32(*(u_int32_t *) *(pptr)); \
102    ((PVFS_ds_keyval *)pbuf)->buffer_sz = len; \
103    ((PVFS_ds_keyval *)pbuf)->buffer = *(pptr) + 4; \
104    *(pptr) += roundup8(4 + len); \
105} while (0)
106
107/*
108 * Type maps are put near the type definitions, except for this special one.
109 *
110 * Please remember when changing a fundamental type, e.g. PVFS_size, to update
111 * also the set of #defines that tell the encoder what its type really is.
112 */
113#define encode_enum encode_int32_t
114#define decode_enum decode_int32_t
115
116/* memory alloc and free, just for decoding */
117#if 0
118/* this is for debugging, if you want to see what is malloc'd */
119static inline void *decode_malloc (int n) {
120        void *p;
121        if (n>0)
122                p = malloc(n);
123        else
124                p = (void *)0;
125        printf("decode malloc %d bytes: %p\n",n,p);
126        return p;
127}
128/* this is for debugging, if you want to see what is free'd */
129static inline void decode_free (void *p) {
130        printf("decode free: %p\n",p);
131        free(p);
132}
133#else
134#define decode_malloc(n) ((n) ? malloc(n) : 0)
135#define decode_free(n) free(n)
136#endif
137
138/*
139 * These wrappers define functions to do the encoding of the types or
140 * structures they describe.  Please remember to update the empty stub versions
141 * of these routines in include/pvfs2-encode-stubs.h, although the compiler
142 * will certainly complain too.
143 *
144 * Note that decode can not take a const since we point into the
145 * undecoded buffer for strings.
146 */
147#define endecode_fields_1_generic(name, sname, t1, x1) \
148static inline void encode_##name(char **pptr, const sname *x) { \
149    encode_##t1(pptr, &x->x1); \
150} \
151static inline void decode_##name(char **pptr, sname *x) { \
152    decode_##t1(pptr, &x->x1); \
153}
154
155#define endecode_fields_1(name, t1, x1) \
156    endecode_fields_1_generic(name, name, t1, x1)
157#define endecode_fields_1_struct(name, t1, x1) \
158    endecode_fields_1_generic(name, struct name, t1, x1)
159
160#define endecode_fields_2_generic(name, sname, t1, x1, t2, x2) \
161static inline void encode_##name(char **pptr, const sname *x) { \
162    encode_##t1(pptr, &x->x1); \
163    encode_##t2(pptr, &x->x2); \
164} \
165static inline void decode_##name(char **pptr, sname *x) { \
166    decode_##t1(pptr, &x->x1); \
167    decode_##t2(pptr, &x->x2); \
168}
169
170#define endecode_fields_2(name, t1, x1, t2, x2) \
171    endecode_fields_2_generic(name, name, t1, x1, t2, x2)
172#define endecode_fields_2_struct(name, t1, x1, t2, x2) \
173    endecode_fields_2_generic(name, struct name, t1, x1, t2, x2)
174
175#define endecode_fields_3_generic(name, sname, t1, x1, t2, x2, t3, x3) \
176static inline void encode_##name(char **pptr, const sname *x) { \
177    encode_##t1(pptr, &x->x1); \
178    encode_##t2(pptr, &x->x2); \
179    encode_##t3(pptr, &x->x3); \
180} \
181static inline void decode_##name(char **pptr, sname *x) { \
182    decode_##t1(pptr, &x->x1); \
183    decode_##t2(pptr, &x->x2); \
184    decode_##t3(pptr, &x->x3); \
185}
186
187#define endecode_fields_3(name, t1, x1, t2, x2, t3, x3) \
188    endecode_fields_3_generic(name, name, t1, x1, t2, x2, t3, x3)
189#define endecode_fields_3_struct(name, t1, x1, t2, x2, t3, x3) \
190    endecode_fields_3_generic(name, struct name, t1, x1, t2, x2, t3, x3)
191
192#define endecode_fields_4_struct(name, t1, x1, t2, x2, t3, x3, t4, x4) \
193static inline void encode_##name(char **pptr, const struct name *x) { \
194    encode_##t1(pptr, &x->x1); \
195    encode_##t2(pptr, &x->x2); \
196    encode_##t3(pptr, &x->x3); \
197    encode_##t4(pptr, &x->x4); \
198} \
199static inline void decode_##name(char **pptr, struct name *x) { \
200    decode_##t1(pptr, &x->x1); \
201    decode_##t2(pptr, &x->x2); \
202    decode_##t3(pptr, &x->x3); \
203    decode_##t4(pptr, &x->x4); \
204}
205
206#define endecode_fields_5_struct(name, t1, x1, t2, x2, t3, x3, t4, x4, t5, x5) \
207static inline void encode_##name(char **pptr, const struct name *x) { \
208    encode_##t1(pptr, &x->x1); \
209    encode_##t2(pptr, &x->x2); \
210    encode_##t3(pptr, &x->x3); \
211    encode_##t4(pptr, &x->x4); \
212    encode_##t5(pptr, &x->x5); \
213} \
214static inline void decode_##name(char **pptr, struct name *x) { \
215    decode_##t1(pptr, &x->x1); \
216    decode_##t2(pptr, &x->x2); \
217    decode_##t3(pptr, &x->x3); \
218    decode_##t4(pptr, &x->x4); \
219    decode_##t5(pptr, &x->x5); \
220}
221
222#define endecode_fields_7_struct(name,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7) \
223static inline void encode_##name(char **pptr, const struct name *x) { \
224    encode_##t1(pptr, &x->x1); \
225    encode_##t2(pptr, &x->x2); \
226    encode_##t3(pptr, &x->x3); \
227    encode_##t4(pptr, &x->x4); \
228    encode_##t5(pptr, &x->x5); \
229    encode_##t6(pptr, &x->x6); \
230    encode_##t7(pptr, &x->x7); \
231} \
232static inline void decode_##name(char **pptr, struct name *x) { \
233    decode_##t1(pptr, &x->x1); \
234    decode_##t2(pptr, &x->x2); \
235    decode_##t3(pptr, &x->x3); \
236    decode_##t4(pptr, &x->x4); \
237    decode_##t5(pptr, &x->x5); \
238    decode_##t6(pptr, &x->x6); \
239    decode_##t7(pptr, &x->x7); \
240}
241
242#define endecode_fields_8_struct(name,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8) \
243static inline void encode_##name(char **pptr, const struct name *x) { \
244    encode_##t1(pptr, &x->x1); \
245    encode_##t2(pptr, &x->x2); \
246    encode_##t3(pptr, &x->x3); \
247    encode_##t4(pptr, &x->x4); \
248    encode_##t5(pptr, &x->x5); \
249    encode_##t6(pptr, &x->x6); \
250    encode_##t7(pptr, &x->x7); \
251    encode_##t8(pptr, &x->x8); \
252} \
253static inline void decode_##name(char **pptr, struct name *x) { \
254    decode_##t1(pptr, &x->x1); \
255    decode_##t2(pptr, &x->x2); \
256    decode_##t3(pptr, &x->x3); \
257    decode_##t4(pptr, &x->x4); \
258    decode_##t5(pptr, &x->x5); \
259    decode_##t6(pptr, &x->x6); \
260    decode_##t7(pptr, &x->x7); \
261    decode_##t8(pptr, &x->x8); \
262}
263
264#define endecode_fields_12(name,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12) \
265static inline void encode_##name(char **pptr, const name *x) { \
266    encode_##t1(pptr, &x->x1); \
267    encode_##t2(pptr, &x->x2); \
268    encode_##t3(pptr, &x->x3); \
269    encode_##t4(pptr, &x->x4); \
270    encode_##t5(pptr, &x->x5); \
271    encode_##t6(pptr, &x->x6); \
272    encode_##t7(pptr, &x->x7); \
273    encode_##t8(pptr, &x->x8); \
274    encode_##t9(pptr, &x->x9); \
275    encode_##t10(pptr, &x->x10); \
276    encode_##t11(pptr, &x->x11); \
277    encode_##t11(pptr, &x->x12); \
278} \
279static inline void decode_##name(char **pptr, name *x) { \
280    decode_##t1(pptr, &x->x1); \
281    decode_##t2(pptr, &x->x2); \
282    decode_##t3(pptr, &x->x3); \
283    decode_##t4(pptr, &x->x4); \
284    decode_##t5(pptr, &x->x5); \
285    decode_##t6(pptr, &x->x6); \
286    decode_##t7(pptr, &x->x7); \
287    decode_##t8(pptr, &x->x8); \
288    decode_##t9(pptr, &x->x9); \
289    decode_##t10(pptr, &x->x10); \
290    decode_##t11(pptr, &x->x11); \
291    decode_##t11(pptr, &x->x12); \
292}
293
294/* ones with arrays that are allocated in the decode */
295
296/* one field then one array */
297#define endecode_fields_1a_generic(name, sname, t1, x1, tn1, n1, ta1, a1) \
298static inline void encode_##name(char **pptr, const sname *x) { int i; \
299    encode_##t1(pptr, &x->x1); \
300    encode_##tn1(pptr, &x->n1); \
301    for (i=0; i<x->n1; i++) \
302        encode_##ta1(pptr, &(x)->a1[i]); \
303} \
304static inline void decode_##name(char **pptr, sname *x) { int i; \
305    decode_##t1(pptr, &x->x1); \
306    decode_##tn1(pptr, &x->n1); \
307    x->a1 = decode_malloc(x->n1 * sizeof(*x->a1)); \
308    for (i=0; i<x->n1; i++) \
309        decode_##ta1(pptr, &(x)->a1[i]); \
310}
311
312#define endecode_fields_1a(name, t1, x1, tn1, n1, ta1, a1) \
313    endecode_fields_1a_generic(name, name, t1, x1, tn1, n1, ta1, a1)
314#define endecode_fields_1a_struct(name, t1, x1, tn1, n1, ta1, a1) \
315    endecode_fields_1a_generic(name, struct name, t1, x1, tn1, n1, ta1, a1)
316
317/* one field, and array, another field, another array - a special case */
318#define endecode_fields_1a_1a_struct(name, t1,x1, tn1, n1, ta1, a1, t2,x2, tn2, n2, ta2, a2) \
319static inline void encode_##name(char **pptr, const struct name *x) { int i; \
320    encode_##t1(pptr, &x->x1); \
321    encode_##tn1(pptr, &x->n1); \
322    for (i=0; i<x->n1; i++) { int n; n = i; \
323        encode_##ta1(pptr, &(x)->a1[n]); } \
324    encode_##t2(pptr, &x->x2); \
325    encode_##tn2(pptr, &x->n2); \
326    for (i=0; i<x->n2; i++) { int n; n = i; \
327        encode_##ta2(pptr, &(x)->a2[n]); } \
328} \
329static inline void decode_##name(char **pptr, struct name *x) { int i; \
330    decode_##t1(pptr, &x->x1); \
331    decode_##tn1(pptr, &x->n1); \
332    x->a1 = decode_malloc(x->n1 * sizeof(*x->a1)); \
333    for (i=0; i<x->n1; i++) \
334        decode_##ta1(pptr, &(x)->a1[i]); \
335    decode_##t1(pptr, &x->x1); \
336    decode_##tn2(pptr, &x->n2); \
337    x->a2 = decode_malloc(x->n2 * sizeof(*x->a2)); \
338    for (i=0; i<x->n2; i++) \
339        decode_##ta2(pptr, &(x)->a2[i]); \
340}
341
342/* 2 fields, then an array */
343#define endecode_fields_2a_generic(name, sname, t1, x1, t2, x2, tn1, n1, ta1, a1) \
344static inline void encode_##name(char **pptr, const sname *x) { int i; \
345    encode_##t1(pptr, &x->x1); \
346    encode_##t2(pptr, &x->x2); \
347    encode_##tn1(pptr, &x->n1); \
348    for (i=0; i<x->n1; i++) \
349        encode_##ta1(pptr, &(x)->a1[i]); \
350} \
351static inline void decode_##name(char **pptr, sname *x) { int i; \
352    decode_##t1(pptr, &x->x1); \
353    decode_##t2(pptr, &x->x2); \
354    decode_##tn1(pptr, &x->n1); \
355    x->a1 = decode_malloc(x->n1 * sizeof(*x->a1)); \
356    for (i=0; i<x->n1; i++) \
357        decode_##ta1(pptr, &(x)->a1[i]); \
358}
359
360#define endecode_fields_2a(name, t1, x1, t2, x2, tn1, n1, ta1, a1) \
361    endecode_fields_2a_generic(name, name, t1, x1, t2, x2, tn1, n1, ta1, a1)
362#define endecode_fields_2a_struct(name, t1, x1, t2, x2, tn1, n1, ta1, a1) \
363    endecode_fields_2a_generic(name, struct name, t1, x1, t2, x2, tn1, n1, ta1, a1)
364
365/* 3 fields, then an array */
366#define endecode_fields_3a_struct(name, t1, x1, t2, x2, t3, x3, tn1, n1, ta1, a1) \
367static inline void encode_##name(char **pptr, const struct name *x) { int i; \
368    encode_##t1(pptr, &x->x1); \
369    encode_##t2(pptr, &x->x2); \
370    encode_##t3(pptr, &x->x3); \
371    encode_##tn1(pptr, &x->n1); \
372    for (i=0; i<x->n1; i++) \
373        encode_##ta1(pptr, &(x)->a1[i]); \
374} \
375static inline void decode_##name(char **pptr, struct name *x) { int i; \
376    decode_##t1(pptr, &x->x1); \
377    decode_##t2(pptr, &x->x2); \
378    decode_##t3(pptr, &x->x3); \
379    decode_##tn1(pptr, &x->n1); \
380    x->a1 = decode_malloc(x->n1 * sizeof(*x->a1)); \
381    for (i=0; i<x->n1; i++) \
382        decode_##ta1(pptr, &(x)->a1[i]); \
383}
384
385/* special case where we have two arrays of the same size after 3 fields */
386#define endecode_fields_3aa_struct(name, t1, x1, t2, x2, t3, x3, tn1, n1, ta1, a1, ta2, a2) \
387static inline void encode_##name(char **pptr, const struct name *x) { int i; \
388    encode_##t1(pptr, &x->x1); \
389    encode_##t2(pptr, &x->x2); \
390    encode_##t3(pptr, &x->x3); \
391    encode_##tn1(pptr, &x->n1); \
392    for (i=0; i<x->n1; i++) \
393        encode_##ta1(pptr, &(x)->a1[i]); \
394    for (i=0; i<x->n1; i++) \
395        encode_##ta2(pptr, &(x)->a2[i]); \
396} \
397static inline void decode_##name(char **pptr, struct name *x) { int i; \
398    decode_##t1(pptr, &x->x1); \
399    decode_##t2(pptr, &x->x2); \
400    decode_##t3(pptr, &x->x3); \
401    decode_##tn1(pptr, &x->n1); \
402    x->a1 = decode_malloc(x->n1 * sizeof(*x->a1)); \
403    for (i=0; i<x->n1; i++) \
404        decode_##ta1(pptr, &(x)->a1[i]); \
405    x->a2 = decode_malloc(x->n1 * sizeof(*x->a2)); \
406    for (i=0; i<x->n1; i++) \
407        decode_##ta2(pptr, &(x)->a2[i]); \
408}
409
410/* special case where we have two arrays of the same size after 4 fields */
411#define endecode_fields_4aa_struct(name, t1, x1, t2, x2, t3, x3, t4, x4, tn1, n1, ta1, a1, ta2, a2) \
412static inline void encode_##name(char **pptr, const struct name *x) { int i; \
413    encode_##t1(pptr, &x->x1); \
414    encode_##t2(pptr, &x->x2); \
415    encode_##t3(pptr, &x->x3); \
416    encode_##t4(pptr, &x->x4); \
417    encode_##tn1(pptr, &x->n1); \
418    for (i=0; i<x->n1; i++) \
419        encode_##ta1(pptr, &(x)->a1[i]); \
420    for (i=0; i<x->n1; i++) \
421        encode_##ta2(pptr, &(x)->a2[i]); \
422} \
423static inline void decode_##name(char **pptr, struct name *x) { int i; \
424    decode_##t1(pptr, &x->x1); \
425    decode_##t2(pptr, &x->x2); \
426    decode_##t3(pptr, &x->x3); \
427    decode_##t4(pptr, &x->x4); \
428    decode_##tn1(pptr, &x->n1); \
429    x->a1 = decode_malloc(x->n1 * sizeof(*x->a1)); \
430    for (i=0; i<x->n1; i++) \
431        decode_##ta1(pptr, &(x)->a1[i]); \
432    x->a2 = decode_malloc(x->n1 * sizeof(*x->a2)); \
433    for (i=0; i<x->n1; i++) \
434        decode_##ta2(pptr, &(x)->a2[i]); \
435}
436
437
438/* 4 fields, then an array */
439#define endecode_fields_4a_struct(name, t1, x1, t2, x2, t3, x3, t4, x4, tn1,n1,ta1,a1) \
440static inline void encode_##name(char **pptr, const struct name *x) { int i; \
441    encode_##t1(pptr, &x->x1); \
442    encode_##t2(pptr, &x->x2); \
443    encode_##t3(pptr, &x->x3); \
444    encode_##t4(pptr, &x->x4); \
445    encode_##tn1(pptr, &x->n1); \
446    for (i=0; i<x->n1; i++) \
447        encode_##ta1(pptr, &(x)->a1[i]); \
448} \
449static inline void decode_##name(char **pptr, struct name *x) { int i; \
450    decode_##t1(pptr, &x->x1); \
451    decode_##t2(pptr, &x->x2); \
452    decode_##t3(pptr, &x->x3); \
453    decode_##t4(pptr, &x->x4); \
454    decode_##tn1(pptr, &x->n1); \
455    x->a1 = decode_malloc(x->n1 * sizeof(*x->a1)); \
456    for (i=0; i<x->n1; i++) \
457        decode_##ta1(pptr, &(x)->a1[i]); \
458}
459
460/* 5 fields, then an array */
461#define endecode_fields_5a_struct(name, t1, x1, t2, x2, t3, x3, t4, x4, t5, x5, tn1,n1,ta1,a1) \
462static inline void encode_##name(char **pptr, const struct name *x) { int i; \
463    encode_##t1(pptr, &x->x1); \
464    encode_##t2(pptr, &x->x2); \
465    encode_##t3(pptr, &x->x3); \
466    encode_##t4(pptr, &x->x4); \
467    encode_##t5(pptr, &x->x5); \
468    encode_##tn1(pptr, &x->n1); \
469    for (i=0; i<x->n1; i++) \
470        encode_##ta1(pptr, &(x)->a1[i]); \
471} \
472static inline void decode_##name(char **pptr, struct name *x) { int i; \
473    decode_##t1(pptr, &x->x1); \
474    decode_##t2(pptr, &x->x2); \
475    decode_##t3(pptr, &x->x3); \
476    decode_##t4(pptr, &x->x4); \
477    decode_##t5(pptr, &x->x5); \
478    decode_##tn1(pptr, &x->n1); \
479    x->a1 = decode_malloc(x->n1 * sizeof(*x->a1)); \
480    for (i=0; i<x->n1; i++) \
481        decode_##ta1(pptr, &(x)->a1[i]); \
482}
483
484#endif  /* __SRC_PROTO_ENDECODE_FUNCS_H */
Note: See TracBrowser for help on using the browser.