/* 1300, Wed 10 Sep 97

   NMC_C64.H:  Counter64 defines to complement nmc_c64.c.
                  Could become a 64-bit class one day ...

   Copyright (C) 1997-2002 by Nevil Brownlee,
   CAIDA | University of Auckland */


/*
 * $Log: nmc_c64.h,v $
 * Revision 1.1.1.2.2.8  2002/02/23 01:57:21  nevil
 * Moving srl examples to examples/ directory.  Modified examples/Makefile.in
 *
 * Revision 1.1.1.2.2.4  2000/06/06 03:38:12  nevil
 * Combine NEW_ATR with TCP_ATR, various bug fixes
 *
 * Revision 1.1.1.2.2.1  1999/11/29 00:17:21  nevil
 * Make changes to support NetBSD on an Alpha (see version.history for details)
 *
 * Revision 1.1.1.2  1999/10/03 21:06:17  nevil
 * *** empty log message ***
 *
 * Revision 1.1.1.1.2.1  1999/01/08 01:38:32  nevil
 * Distribution file for 4.3b7
 *
 * Revision 1.1.1.1  1998/11/16 03:57:27  nevil
 * Import of NeTraMet 4.3b3
 *
 * Revision 1.1.1.1  1998/11/16 03:22:00  nevil
 * Import of release 4.3b3
 *
 * Revision 1.1.1.1  1998/10/28 20:31:25  nevil
 * Import of NeTraMet 4.3b1
 *
 * Revision 1.1.3.2  1998/10/18 23:44:10  nevil
 * Added Nicolai's patches, some 'tidying up' of the source
 *
 * Revision 1.1.3.1  1998/10/13 02:48:23  nevil
 * Import of Nicolai's 4.2.2
 *
 * Revision 1.1.1.1  1998/08/24 12:09:28  nguba
 * NetraMet 4.2 Original Distribution
 *
 * Revision 1.3  1998/05/07 04:28:53  rtfm
 * Implement NetFlowMet, the Cisco NetFlow RTFM meter
 */


char *putc64(char *bp, counter64 *c);  /* 64-bit output */
char *getc64(counter64 *c, char *bp);  /* 64-bit input */


#if SIZEOF_LONG_LONG == 8 || SIZEOF_LONG == 8

#define nz64(c64)  \
   (c64 != 0)
#define diff64(r32, c64,x64)  {  \
   r32 = c64 - x64; \
   }
#define ratio64(r32, c64,x64)  {  \
   r32 = c64 / x64;  \
   }
#define sum64(r32, c64,x64)  {  \
   r32 = c64 + x64;  \
   }

#define add64(r64, c64,x64) {  \
   r64 = c64 + x64;  \
   }
#define subtr64(r64, c64,x64) {  \
   r64 = c64 - x64;  \
   }
#define assign64(x64,y64)  {  \
   x64 = y64;  \
   }
#define zero64(c64)  c64 = 0
#define eq64p(x64,y64)  (*x64 == *y64)
#define double64p(x64)  ((double)*x64)

#define add_Bit32_to_counter64(c64,u32)  {  \
   c64 += u32;  \
   }
#define incr_counter64(c64)  {  \
   ++c64;  \
   }

#define fraction64(c64,x)  (c64 / x)

#elif SIZEOF_LONG == 4

#define nz64(c64)  \
   (c64.low != 0 || c64.high != 0)
#define diff64(r32, c64,x64)  {  \
   r32 = c64.low - x64.low;  \
   }
#define ratio64(r32, c64,x64)  {  \
   r32 = c64.low / x64.low;  \
   }
#define sum64(r32, c64,x64)  {  \
   r32 = c64.low + x64.low;  \
   }

#define add64(r64, c64,x64) {  \
   if ((r64.low = c64.low + x64.low) < c64.low) \
      r64.high = c64.high + 1 + x64.high;  \
   else r64.high = c64.high + x64.high;  \
   }
#define subtr64(r64, c64,x64) {  \
   if ((r64.low = c64.low - x64.low) > c64.low) \
      r64.high = c64.high - 1 - x64.high;  \
   else r64.high = c64.high - x64.high;  \
   }
#define assign64(x64,y64)  {  \
   x64.high = y64.high;  x64.low = y64.low;  \
   }
#define zero64(c64)  c64.high = c64.low = 0

#define eq64p(x64,y64)  (x64->low == y64->low && x64->high == y64->high)
#define DWORD_SIZE    4294967296.0      /* 4G */
#define double64p(x64)  (x64->high*(double)DWORD_SIZE + (double)x64->low)

#define add_Bit32_to_counter64(c64,u32)  {  \
   c64arg = c64.low;  if ((c64.low += (u32)) < c64arg) ++c64.high;  \
   }
#define incr_counter64(c64)  {  \
   c64arg = c64.low;  if (++c64.low < c64arg) ++c64.high;  \
   }

#define fraction64(c64,x)  (c64.low / x)

EXTERN Bit32 c64arg;  /* Work variable for defines above */

#else
#error  sizeof(long) not 4 or 8 <<<<<<<<
#endif
