#ifndef NETORDER_H
#define NETORDER_H

#include "sysfuncs.h"

/* [RPAP - Feb 97: WIN32 Port] */
#ifdef __WIN32__
#include "win32in.h"
#else
# include <netinet/in.h>
#endif

#ifndef WORDS_BIGENDIAN

/* double */
#define HTOND(d)                                                              \
        do {                                                                  \
             mg_u_long tmph, tmpl;                                        \
	     memcpy ((void *) &tmph, (const void *) &d, sizeof(double) >> 1); \
	     memcpy ((void *) &tmpl, (const void *) ((unsigned char*) &d + (sizeof(double) >> 1)), sizeof (double) >> 1);   \
	     tmph = htonl (tmph);                                             \
	     tmpl = htonl (tmpl);                                             \
	     memcpy ( (void *) &d, (const void *) &tmpl, sizeof (double) >> 1);                           \
	     memcpy ((void *) ((unsigned char*) &d + (sizeof(double) >> 1)), (const void *) &tmph, sizeof (double) >> 1);   \
	}while(0)
#define NTOHD(d)                                                              \
        do {                                                                  \
             mg_u_long tmph, tmpl;                                        \
	     memcpy ((void *) &tmph, (const void *) &d, sizeof(double) >> 1); \
	     memcpy ((void *) &tmpl, (const void *) ((unsigned char*) &d + (sizeof(double) >> 1)), sizeof (double) >> 1);   \
	     tmph = ntohl (tmph);                                             \
	     tmpl = ntohl (tmpl);                                             \
	     memcpy((void *) &d, (const void *) &tmpl, sizeof (double) >> 1); \
	     memcpy ((void *) ((unsigned char*) &d + (sizeof(double) >> 1)), (const void *) &tmph, sizeof (double) >> 1);   \
        }while(0)
#define HTOND2(hd, nd)                                                        \
        do {                                                                  \
             mg_u_long tmph, tmpl;                                        \
	     memcpy ((void *) &tmph, (const void *) &hd, sizeof(double) >> 1);\
	     memcpy ((void *) &tmpl, (const void *) ((unsigned int) &hd + (sizeof(double) >> 1)), sizeof (double) >> 1);  \
	     tmph = htonl (tmph);                                             \
	     tmpl = htonl (tmpl);                                             \
	     memcpy((void *) &nd, (const void *) &tmpl, sizeof (double) >> 1);\
	     memcpy ((void *) ((unsigned int) &nd + (sizeof(double) >> 1)), (void *) &tmph, sizeof (double) >> 1);  \
	}while(0)
#define NTOHD2(nd, hd)                                                        \
        do {                                                                  \
             mg_u_long tmph, tmpl;                                        \
	     memcpy ((void *) &nd, (void *) &tmph, sizeof(double) >> 1);      \
	     memcpy ((void *) &tmpl, (const void *) &nd + (sizeof(double) >> 1), sizeof (double) >> 1);  \
	     tmph = ntohl (tmph);                                             \
	     tmpl = ntohl (tmpl);                                             \
	     memcpy((void *) &hd, (const void *) &tmpl, sizeof (double) >> 1);\
	     memcpy ((void *) &hd + (sizeof(double) >> 1), (const void *) &tmph, sizeof (double) >> 1);  \
        }while(0)

/* float */
#define HTONF(f)                                                              \
        do {                                                                  \
             mg_u_long tmp;                                               \
             memcpy ((void *) &tmp, (const void *) &(f), sizeof (float));     \
             HTONUL (tmp);                                                    \
	     memcpy ((void *) &(f), (const void *) &tmp, sizeof (float));     \
	}while(0)
#define NTOHF(f)                                                              \
        do {                                                                  \
             mg_u_long tmp;                                               \
             memcpy ((void *) &tmp, (const void *) &(f), sizeof (float));     \
	     NTOHUL (tmp);                                                    \
	     memcpy ((void *) &(f), (const void *) &tmp, sizeof (float));     \
	}while(0)
#define HTONF2(hf, nf)                                                        \
        do {                                                                  \
             mg_u_long tmp;                                               \
             memcpy ((void *) &tmp, (const void *) &(hf), sizeof (float));    \
             HTONUL (tmp);                                                    \
	     memcpy ((void *) &(nf), (const void *) &tmp, sizeof (float));    \
	}while(0)
#define NTOHF2(nf, hf)                                                        \
        do {                                                                  \
             mg_u_long tmp;                                               \
             memcpy ((void *) &tmp, (const void *) &(nf), sizeof (float));    \
	     NTOHUL (tmp);                                                    \
	     memcpy ((void *) &(hf), (const void *) &tmp, sizeof (float));    \
	}while(0)

#ifdef __MINGW32__

static inline short reverseShort(short s) 
{    
  unsigned char c1 = s & 255;
  unsigned char c2 = (s >> 8) & 255;
    
  return (c1 << 8) | c2;
}

static inline int reverseInt (int i) 
{
  unsigned char c1 = i & 255;
  unsigned char c2 = (i >> 8) & 255;
  unsigned char c3 = (i >> 16) & 255;
  unsigned char c4 = (i >> 24) & 255;

  return ((int)c1 << 24) | ((int)c2 << 16) | ((int)c3 << 8) | c4;
}

#define htonl(l) reverseInt(l)
#define htons(s) reverseShort(s)
#define ntohl(l) reverseInt(l)
#define ntohs(s) reverseShort(s)

#endif


/* pointers */
#define HTONP(p)          ((p) = (void *) htonl ((mg_u_long) p))
#define NTOHP(p)          ((p) = (void *) ntohl ((mg_u_long) p))
#define HTONP2(hp, np)    ((np) = (void *) htonl ((mg_u_long) hp))
#define NTOHP2(np, hp)    ((hp) = (void *) ntohl ((mg_u_long) np))

/* unsigned long */
#define HTONUL(l)         ((l) = htonl((l)))
#define NTOHUL(l)         ((l) = ntohl((l)))
#define HTONUL2(hl, nl)   ((nl) = htonl ((hl)))
#define NTOHUL2(nl, hl)   ((hl) = ntohl ((nl)))

/* signed long */
#define HTONSL(l)         ((l) = (mg_s_long) htonl ((mg_u_long) (l)))
#define NTOHSL(l)         ((l) = (mg_s_long) ntohl ((mg_u_long) (l)))
#define HTONSL2(hl, nl)   ((nl) = (mg_s_long) htonl ((mg_u_long) (hl)))
#define NTOHSL2(nl, hl)   ((hl) = (mg_s_long) ntohl ((mg_u_long) (nl)))

/* unsigned int */
#define HTONUI(i)         ((i) = (unsigned int) htonl ((mg_u_long) (i)))
#define NTOHUI(i)         ((i) = (unsigned int) ntohl ((mg_u_long) (i)))
#define HTONUI2(hi, ni)   ((ni) = (unsigned int) htonl ((mg_u_long) (hi)))
#define NTOHUI2(ni, hi)   ((hi) = (unsigned int) ntohl ((mg_u_long) (ni)))

/* signed int */
#define HTONSI(i)         ((i) = (int) htonl ((mg_u_long) (i)))
#define NTOHSI(i)         ((i) = (int) ntohl ((mg_u_long) (i)))
#define HTONSI2(hi, ni)   ((ni) = (int) htonl ((mg_u_long) (hi)))
#define NTOHSI2(ni, hi)   ((hi) = (int) ntohl ((mg_u_long) (ni)))

/* unsigned short */
#define HTONUS(s)         ((s) = htons((s)))
#define NTOHUS(s)         ((s) = ntohs((s)))
#define HTONUS2(hs, ns)   ((ns) = htons((hs)))
#define NTOHUS2(ns, hs)   ((hs) = ntohs((ns)))

#else   /* WORDS_BIGENDIAN */

/* double */
#define HTOND(d)          (d)
#define NTOHD(d)          (d)
#define HTOND2(hd, nd)    ((hd) = (nd))
#define NTOHD2(nd, hd)    ((nd) = (hd))

/* float */
#define HTONF(f)          (f)
#define NTOHF(f)          (f)
#define HTONF2(hf, nf)    ((nf) = (hf))
#define NTOHF2(nf, hf)    ((hf) = (nf))

/* pointers */
#define HTONP(p)          (p)
#define NTOHP(p)          (p)
#define HTONP2(hp, np)    ((np) = (hp))
#define NTOHP2(np, hp)    ((hp) = (np))

/* unsigned long */
#define HTONUL(l)         (l)
#define NTOHUL(l)         (l)
#define HTONUL2(hl, nl)   ((nl) = (hl))
#define NTOHUL2(nl, hl)   ((hl) = (nl))

/* signed long */
#define HTONSL(l)         (l)
#define NTOHSL(l)         (l)
#define HTONSL2(hl, nl)   ((nl) = (hl))
#define NTOHSL2(nl, hl)   ((hl) = (nl))

/* unsigned int */
#define HTONUI(i)         (i)
#define NTOHUI(i)         (i)
#define HTONUI2(hi, ni)   ((ni) = (hi))
#define NTOHUI2(ni, hi)   ((hi) = (ni))

/* signed int */
#define HTONSI(i)         (i)
#define NTOHSI(i)         (i)
#define HTONSI2(hi, ni)   ((ni) = (hi))
#define NTOHSI2(ni, hi)   ((hi) = (ni))

/* unsigned short */
#define HTONUS(s)         (s)
#define NTOHUS(s)         (s)
#define HTONUS2(hs, ns)   ((ns) = (hs))
#define NTOHUS2(ns, hs)   ((hs) = (ns))



#endif

#endif /* netorder.h */
