sources/machdepnetmacros.h

// 
// Apple Macintosh Developer Technical Support
// Written by:  Vinnie Moscaritolo
//
//  Copyright (work in progress)  Apple Computer, Inc All rights reserved.
//
// You may incorporate this sample code into your applications without
// restriction, though the sample code has been provided "AS IS" and the
// responsibility for its operation is 100% yours.  However, what you are
// not permitted to do is to redistribute the source as "DSC Sample Code"
// after having made changes. If you're going to re-distribute the source,
// we require that you make it clear in the source that the code was
// descended from Apple Sample Code, but that you've made changes.
// 
//
// file :machdepnetmacros.h
// This module contains the machine dependent network definition
//
 
// If this is Microsoft Visual C++, disable warnings about unknown pragmas 
// such as #pragma mark
 
#ifdef _MSC_VER
#pragma warning(disable:4068)
#endif
 
#include <ConditionalMacros.h>
 
 /* TARGET_RT_LITTLE_ENDIAN controls whether messages are byte-swapped. 
 The choices are TARGET_RT_LITTLE_ENDIAN(default) and TARGET_RT_BIG_ENDIAN. */
 
 
/* ALIGN controls whether move operations must be aligned on natural boundaries.
 * If ALIGN == 1, all move instructions must have aligned operands.
 * If ALIGN == 0 (default), hardware does not require data alignment. */
 
#ifndef ALIGN
#if TARGET_OS_MAC
#include <string.h>
#define ALIGN                   1
#else
#define ALIGN                   0
#endif
#endif
 
// ---------------------------------------------------------------------------
// Primitive Datatypes *
// ---------------------------------------------------------------------------
 
typedef unsigned char           UByte1;                 /* unsigned 8 bit quantity */
typedef unsigned short          UByte2;                 /* unsigned 16 bit quantity */
typedef unsigned long           UByte4;                 /* unsigned 32 bit quantity */
typedef unsigned long long      UByte8;                 /* unsigned 64 bit quantity */
typedef void *                  Opaque;                 /* pointer to arbitrary block */
 
typedef UByte4                      NetworkTime;
 
 
/* MOVE_NET macros */
 
// Move on byte to/from a message buffer
 
#ifdef TARGET_OS_MAC
#define MOVE_TO_NET_1(wireMsgP, v)      { *((UByte1*)wireMsgP)++ =  (v) & 0xff; }
#else
#define MOVE_TO_NET_1(wireMsgP, v)      { *((UByte1*)wireMsgP)++ = (UByte1)(v);}
#endif
#define MOVE_FROM_NET_1(wireMsgP, v)        {(v) = *((UByte1*)wireMsgP)++;}
 
#define SKIP_TO_NET_1(wireMsgP)     { ((UByte1*)wireMsgP)+=1;}
#define SKIP_TO_NET_2(wireMsgP)     { ((UByte1*)wireMsgP)+=2;}
#define SKIP_TO_NET_4(wireMsgP)     { ((UByte1*)wireMsgP)+=4;}
#define SKIP_TO_NET_8(wireMsgP)     { ((UByte1*)wireMsgP)+=8;}
 
#define SKIP_FROM_NET_1(wireMsgP)       { ((UByte1*)wireMsgP)+=1;}
#define SKIP_FROM_NET_2(wireMsgP)       { ((UByte1*)wireMsgP)+=2;}
#define SKIP_FROM_NET_4(wireMsgP)       { ((UByte1*)wireMsgP)+=4;}
#define SKIP_FROM_NET_8(wireMsgP)       { ((UByte1*)wireMsgP)+=8;}
 
#define SKIP_FROM_NET(wireMsgP, length) { ((UByte1*)wireMsgP)+=length;}
#define SKIP_TO_NET (wireMsgP, length)  { ((UByte1*)wireMsgP)+=length;}
 
 
// Move a block to/from a message buffer
 
#define COPY_FROM_TO(from, to, length)      memmove((to), (from), (size_t)(length));
 
#define MEM_ZERO(memP, size)                    {UByte1 *_p =  (UByte1*) memP;  size_t _len = (size_t)size;  while(_len--)*_p++ = 0;  }
 
#define MOVE_FROM_NET_BLOCK(wireMsgP, v, len)       { COPY_FROM_TO((UByte1*)wireMsgP, (UByte1*)v , len); ((UByte1 *)wireMsgP)+=len;}
#define MOVE_TO_NET_BLOCK(wireMsgP, v, len)         { COPY_FROM_TO((UByte1*)v, (UByte1*)wireMsgP, len);  ((UByte1 *)wireMsgP)+=len;}
 
 
 
// move to net in order
 
#define MOVE_TO_NET_NUMERIC_2(wireMsgP, v)                      \
    {                                                           \
    MOVE_TO_NET_1 (wireMsgP, (v)>>8 )                           \
    MOVE_TO_NET_1 (wireMsgP, (v)>>0 )                           \
    }
 
#define MOVE_TO_NET_NUMERIC_4(wireMsgP, v)                      \
    {                                                           \
    MOVE_TO_NET_1 (wireMsgP, (v)>>24)                           \
    MOVE_TO_NET_1 (wireMsgP, (v)>>16)                           \
    MOVE_TO_NET_1 (wireMsgP, (v)>>8 )                           \
    MOVE_TO_NET_1 (wireMsgP, (v)>>0 )                           \
    }
 
#define MOVE_TO_NET_NUMERIC_8(wireMsgP, v)                      \
    {                                                           \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>56)                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>48)                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>40)                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>32)                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>24)                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>16)                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>8 )                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>0 )                          \
    }
 
#define MOVE_FROM_NET_NUMERIC_2(wireMsgP, v)                    \
    {                                                                       \
    (v) =  (*((UByte1*)wireMsgP)++ << 8 )                       \
        +  (*((UByte1*)wireMsgP)++ << 0 );                      \
    }
 
#define MOVE_FROM_NET_NUMERIC_4(wireMsgP, v)                    \
    {                                                                       \
        UByte4  _uh, _lh;                                           \
        MOVE_FROM_NET_NUMERIC_2(wireMsgP,  _uh)                 \
        MOVE_FROM_NET_NUMERIC_2(wireMsgP , _lh)                 \
        (v) = (_uh << 16) + (0xFFFF & _lh)  ;                   \
    }
 
#define MOVE_FROM_NET_NUMERIC_8(wireMsgP, v)                    \
    {                                                                       \
        UByte8  _uh, _lh;                                           \
        MOVE_FROM_NET_NUMERIC_4(wireMsgP,  _uh)                 \
        MOVE_FROM_NET_NUMERIC_4(wireMsgP , _lh)                 \
        (v) = (_uh << 32) + (0xFFFFFFFF & _lh) ;                \
    }
    
 
// move to net swapped order
 
#define MOVE_TO_NET_REVERSED_2(wireMsgP, v)                         \
    {                                                           \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>0 )                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>8 )                          \
    }
 
#define MOVE_TO_NET_REVERSED_4(wireMsgP,v)                      \
    {                                                           \
    MOVE_TO_NET_1 (wireMsgP, (v)>>0 )                           \
    MOVE_TO_NET_1 (wireMsgP, (v)>>8 )                           \
    MOVE_TO_NET_1 (wireMsgP, (v)>>16)                           \
    MOVE_TO_NET_1 (wireMsgP, (v)>>24)                           \
    }
 
#define MOVE_TO_NET_REVERSED_8(wireMsgP, v)                         \
    {                                                           \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>0 )                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>8 )                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>16)                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>24)                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>32)                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>40)                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>48)                          \
    MOVE_TO_NET_1 (wireMsgP,  (v)>>56)                          \
    }
 
 
 
 
#define MOVE_FROM_NET_REVERSED_2(wireMsgP, v)                   \
    {                                                           \
    (v) = (*((UByte1*)wireMsgP)++ << 0 )                        \
        + (*((UByte1*)wireMsgP)++ << 8 );                       \
    }
 
 
#define MOVE_FROM_NET_REVERSED_4(wireMsgP, v)                   \
    {                                                                       \
        UByte4  _uh, _lh;                                           \
        MOVE_FROM_NET_REVERSED_2(wireMsgP,  _lh)                \
        MOVE_FROM_NET_REVERSED_2(wireMsgP , _uh)                \
        (v) = (_uh << 16) + (0xFFFF & _lh)  ;                   \
    }
 
#define MOVE_FROM_NET_REVERSED_8(wireMsgP, v)                   \
    {                                                                       \
        UByte8  _uh, _lh;                                           \
        MOVE_FROM_NET_REVERSED_2(wireMsgP,  -lh)                \
        MOVE_FROM_NET_REVERSED_2(wireMsgP , _uh)                \
        (v) = (_uh << 32) + (0xFFFFFFFF & _lh) ;                \
    }
 
 
// move macros for machines that require move operations be aligned.
 
#if ALIGN
#if  TARGET_RT_BIG_ENDIAN 
 
#define MOVE_TO_NET_2(wireMsgP, v)      MOVE_TO_NET_NUMERIC_2 (wireMsgP, v)
#define MOVE_TO_NET_4(wireMsgP, v)      MOVE_TO_NET_NUMERIC_4 (wireMsgP, v)
#define MOVE_TO_NET_8(wireMsgP, v)      MOVE_TO_NET_NUMERIC_8 (wireMsgP, v)
#define MOVE_FROM_NET_2(wireMsgP, v)    MOVE_FROM_NET_NUMERIC_2 (wireMsgP, v)
#define MOVE_FROM_NET_4(wireMsgP, v)    MOVE_FROM_NET_NUMERIC_4 (wireMsgP, v)
#define MOVE_FROM_NET_8(wireMsgP, v)    MOVE_FROM_NET_NUMERIC_8 (wireMsgP, v)
 
#else 
 
#define MOVE_TO_NET_2(wireMsgP,  v)         MOVE_TO_NET_REVERSED_2 (wireMsgP, v)
#define MOVE_TO_NET_4(wireMsgP,  v)         MOVE_TO_NET_REVERSED_4 (wireMsgP, v)
#define MOVE_TO_NET_8(wireMsgP,  v)         MOVE_TO_NET_REVERSED_8 (wireMsgP, v)
#define MOVE_FROM_NET_2(wireMsgP, v)        MOVE_FROM_NET_REVERSED_2 (wireMsgP, v)
#define MOVE_FROM_NET_4(wireMsgP, v)        MOVE_FROM_NET_REVERSED_4 (wireMsgP, v)
#define MOVE_FROM_NET_8(wireMsgP, v)        MOVE_FROM_NET_REVERSED_8 (wireMsgP, v)
 
#endif  
 
#else /* ALIGN */
 
#define MOVE_TO_NET_2(wireMsgP, v)          { *((UByte2*)wireMsgP)++ = (UByte2)(v);}
#define MOVE_TO_NET_4(wireMsgP, v)          { *((UByte4*)wireMsgP)++ = (UByte4)(v);}
#define MOVE_TO_NET_4(wireMsgP, v)          { *((UByte8*)wireMsgP)++ = (UByte8)(v);}
#define MOVE_FROM_NET_2(wireMsgP, v)        {(v) =  *((UByte2*)wireMsgP)++;}
#define MOVE_FROM_NET_4(wireMsgP, v)        {(v) =  *((UByte4*)wireMsgP)++;}
#define MOVE_FROM_NET_8(wireMsgP, v)        {(v) =  *((UByte8*)wireMsgP)++;}
 
#endif /* ALIGN */
 
// move macros for big/little endian..
 
#if TARGET_RT_BIG_ENDIAN
 
#define SWAP_TO_NET_2(wireMsgP, v)          MOVE_TO_NET_2 (wireMsgP, v)
#define SWAP_TO_NET_4(wireMsgP, v)          MOVE_TO_NET_4 (wireMsgP, v)
#define SWAP_TO_NET_8(wireMsgP, v)          MOVE_TO_NET_8 (wireMsgP, v)
#define SWAP_FROM_NET_2(wireMsgP, v)        MOVE_FROM_NET_2 (wireMsgP, v)
#define SWAP_FROM_NET_4(wireMsgP, v)        MOVE_FROM_NET_4 (wireMsgP, v)
#define SWAP_FROM_NET_8(wireMsgP, v)        MOVE_FROM_NET_8 (wireMsgP, v)
 
#else  
 
#define SWAP_TO_NET_2(wireMsgP,  v)         MOVE_TO_NET_NUMERIC_2 (wireMsgP,  v)
#define SWAP_TO_NET_4(wireMsgP,  v)         MOVE_TO_NET_NUMERIC_4 (wireMsgP,  v)
#define SWAP_TO_NET_8(wireMsgP,  v)         MOVE_TO_NET_NUMERIC_8 (wireMsgP,  v)
 
#define SWAP_FROM_NET_2(wireMsgP,  v)       MOVE_FROM_NET_NUMERIC_2 (wireMsgP,  v)
#define SWAP_FROM_NET_4(wireMsgP,  v)       MOVE_FROM_NET_NUMERIC_4 (wireMsgP,  v)
#define SWAP_FROM_NET_8(wireMsgP,  v)       MOVE_FROM_NET_NUMERIC_8 (wireMsgP,  v)
 
#endif  
 
// ---------------------------------------------------------------------------
#pragma mark  -- Linked List Operators --
// ---------------------------------------------------------------------------
 
#define INSERT_LIST_HEAD(h, unused_TYP, eP, f)  \
    {                                                                                           \
    (eP)->f = (h);                                                              \
    (h) = (eP);                                                                     \
    }
 
#define IF_REMOVE_LIST_HEAD(h, unused_TYP, eP, f)       \
    if ((eP) = (h)) (h) = (eP)->f;
 
#define INSERT_LIST_TAIL(h, TYP, eP, f)                 \
    {                                                                                           \
    TYP **ePP = (&(h));                                                     \
                                                                                                \
    while (1) {                                                                     \
        if (!(*ePP)) break;                                                 \
        ePP = (&(*ePP)->f);                                                 \
    }                                                                                           \
                                                                                                \
    (*ePP) = (eP);                                                              \
    (eP)->f = 0;                                                                    \
    }
 
#define REMOVE_LIST_ENTRY(h, TYP, eP, f)            \
    {                                                                                       \
    TYP **ePP, **nPP = (&(h));                                  \
                                                                                            \
    while (1) {                                                                 \
        ePP = nPP;                                                              \
        nPP = (&(*nPP)->f);                                             \
        if ((*ePP) == (eP)) break;                              \
    }                                                                                       \
                                                                                            \
    (*ePP) = (eP)->f;                                                       \
    }
 
// ---------------------------------------------------------------------------
#pragma mark  -- Set traversal operations  --
// ---------------------------------------------------------------------------
 
#define FOR_EACH(h, eP, nextEP, f)              for (nextEP = (h); (eP = nextEP) && (nextEP = eP->f, 1); )