#ifndef __PAN_ALIGN_H__ #define __PAN_ALIGN_H__
* Panda3.0 messages have slack space at the end into which each layer can * write its header(s). * For speed, these headers are best aligned (to the header alignment * requirements). However, the popper must know how much alignment space * has been skipped in each message, and this must needs be recorded in * the header. * For ease of use, we provide four macros to generate push, restore * look and pop for headers. To define a header push/restore/pop/look function, * invoke the macro with 2 parameters: function name and header type. * To use these macros, the user MUST provide a field in his header named * "align", which must be assignment compatible with type unsigned char.
#include <stddef.h>
#if defined(do_align) #undef do_align #endif
#if defined(aligned) #undef aligned #endif
/*Must write -1 + (n) since (n) - 1 * translate to (int)(-1), which * would be legal
*/
#define align_of(tp) offsetof(struct{char __a; tp __tp;}, __tp)
#define do_align(a, n) (((a) - 1 + (n)) & ~(-1 + (n)))
#define aligned(a, n) (((a) & (-1 + (n))) == 0)
#define align_to(a, tp) do_align(a, align_of(tp))
#define aligned_to(a, tp) aligned(a, align_of(tp))
#define pan_mk_hdr_push(name, _tp) \
_tp *name(void *msg, int *p_len, _tp *backup) \
{ \
unsigned char align; \
_tp *hdr; \
int len; \
\
len = *p_len; \
align = align_to(len, _tp) - len; \
len += align; \
\
hdr = (_tp*)((char *)msg + len); \
if (backup != NULL) { \
*backup = *hdr; \
} \
hdr->align = align; \
*p_len = len + sizeof(_tp); \
\
return hdr; \
}
#define pan_mk_hdr_restore(name, _tp) \
void name(void *msg, int *p_len, _tp *backup) \
{ \
_tp *hdr; \
\
hdr = (_tp*)((char *)msg + *p_len - sizeof(_tp)); \
*p_len -= hdr->align + sizeof(_tp); \
\
*hdr = *backup; \
}
#define pan_mk_hdr_pop(name, _tp) \
_tp *name(void *msg, int *p_len) \
{ \
_tp *hdr; \
\
hdr = (_tp*)((char *)msg + *p_len - sizeof(_tp)); \
*p_len -= hdr->align + sizeof(_tp); \
\
return hdr; \
}
#define pan_mk_hdr_look(name, _tp) \
_tp *name(void *msg, int len) \
{ \
return (_tp*)((char *)msg + len - sizeof(_tp)); \
}
#endif