/* ---------------------------------------------------------------------
   (c) ED 2003
   Project      : CLIB
   Function     : Host to Network portable conversions
   Module       : HTON
   File         : HTON.C
   Created      : 25-04-2003
   Modified     : 29-11-2006
   --------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
   Log

   1.1 29-11-2006 network functions added nread*(), nwrite*().
   .              *to*() becomes *to*s().
   1.0 25-04-2003 Intial version
   0.0 25-04-2003 Creation

   --------------------------------------------------------------------- */
#ifdef __cplusplus
#error This source file is not C++ but rather C. Please use a C-compiler
#endif

#include "ed/inc/hton.h"
#include "ed/inc/sys.h"

/* macros ============================================================== */

/* Portability issue */

/* x86 : swap-it */
#if defined (__BORLANDC__) \
 || defined (__DJGPP__)    \
 || defined (__GNUC__)
#define swap(a) swap_ (a)
#define swapl(a) swapl_ (a)

/* 68k MPC TMS : do-nothing */
#elif defined (__DIAB) || defined (_TMS320C5XX)

#define swap(a) a
#define swapl(a) a

#else
#error 'swap_' is undefined for this platform

#endif

/* constants =========================================================== */
/* types =============================================================== */
/* structures ========================================================== */
/* private data ======================================================== */
/* private functions =================================================== */

/* ---------------------------------------------------------------------
   --------------------------------------------------------------------- */
static uint swap_ (uint data)
{
   return ((data & 0x00FFU) << 8) | ((data & 0xFF00U) >> 8);
}

/* ---------------------------------------------------------------------
   --------------------------------------------------------------------- */
static ulong swapl_ (ulong data)
{
   return ((data & 0x000000FFUL) << 24)
      | ((data & 0x0000FF00UL) << 8)
      | ((data & 0x00FF0000UL) >> 8) | ((data & 0xFF000000UL) >> 24);
}

/* internal public data ================================================ */
/* internal public functions =========================================== */
/* entry points ======================================================== */

/* ---------------------------------------------------------------------
   --------------------------------------------------------------------- */
uint htons (uint const data_h)
{
   return swap (data_h);
}

/* ---------------------------------------------------------------------
   --------------------------------------------------------------------- */
ulong htonl (ulong const data_h)
{
   return swapl (data_h);
}

/* ---------------------------------------------------------------------
   --------------------------------------------------------------------- */
uint ntohs (uint const data_n)
{
   return swap (data_n);
}

/* ---------------------------------------------------------------------
   --------------------------------------------------------------------- */
ulong ntohl (ulong const data_n)
{
   return swapl (data_n);
}


   /* read or write bytes from/to network */
/* ---------------------------------------------------------------------
   --------------------------------------------------------------------- */
uint nreads (uchar const a[2])
{
   uint data = 0;
   data |= a[0] << (8 * 1);     /* MSB first */
   data |= a[1] << (8 * 0);
   return data;
}

/* ---------------------------------------------------------------------
   --------------------------------------------------------------------- */
void nwrites (uchar a[2], uint data)
{
   a[0] = (data >> (8 * 1)) & 0xFF;     /* MSB first */
   a[1] = (data >> (8 * 0)) & 0xFF;
}

/* ---------------------------------------------------------------------
   --------------------------------------------------------------------- */
ulong nreadl (uchar const a[4])
{
   ulong data = 0;
   data |= a[0] << (8 * 3);     /* MSB first */
   data |= a[1] << (8 * 2);
   data |= a[2] << (8 * 1);
   data |= a[3] << (8 * 0);
   return data;
}

/* ---------------------------------------------------------------------
   --------------------------------------------------------------------- */
void nwritel (uchar a[4], ulong data)
{
   a[0] = (data >> (8 * 3)) & 0xFF;     /* MSB first */
   a[1] = (data >> (8 * 2)) & 0xFF;
   a[2] = (data >> (8 * 1)) & 0xFF;
   a[3] = (data >> (8 * 0)) & 0xFF;
}

/* public data ========================================================= */
