next up previous
Up: The Panda 3.0 Previous: Sending and Receiving

Message header macros

 

#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


Rutger Hofman
Wed Jul 22 18:25:43 MET DST 1998