// Hey, Emacs, this a -*-C++-*- file !
//
// Copyright distributed.net 1997-1999 - All Rights Reserved
// For use in distributed.net projects only.
// Any other distribution or use of this source violates copyright.
// 
// $Log: w32sock.h,v $
// Revision 1.5  1999/01/01 02:45:21  cramer
// Part 1 of 1999 Copyright updates...
//
// Revision 1.4  1998/12/21 15:02:00  cyp
// Added select() support.
//
// Revision 1.3  1998/11/02 05:15:07  cyp
// Added code to search for winsock.dll before using LoadLibrary().
//
// Revision 1.2  1998/10/26 04:25:54  cyp
// Everything works now for the win16 client (tested under win16 Novell,
// Microsoft and Trumpet stacks, as well as the win32 M$ stack)
//
// Revision 1.2  1998/10/19 07:56:11  cyp
// Created
//

#ifndef __WIN32SOCK_H__
#define __WIN32SOCK_H__

#ifndef NO_W32SOCK
  #include <windows.h>
  #ifdef __WINDOWS_386__
  #undef FAR
  #define FAR
  #endif
  #include <winsock.h>
  #ifdef __WINDOWS_386__

  /*FD_ISSET applies a FAR * cast before calling __WSAFDIsSet, so remove it.*/
  #undef FD_ISSET
  #define FD_ISSET(fd, set) __WSAFDIsSet(fd, set)

  /* FD_CLR do {} while(0) loop is always false. Squelch the warning. */
  #undef FD_CLR
  #define FD_CLR(fd, set) do { \
    u_int __i; \
    for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count ; __i++) { \
        if (((fd_set FAR *)(set))->fd_array[__i] == fd) { \
            while (__i < ((fd_set FAR *)(set))->fd_count-1) { \
                ((fd_set FAR *)(set))->fd_array[__i] = \
                    ((fd_set FAR *)(set))->fd_array[__i+1]; \
                __i++; \
            } \
            ((fd_set FAR *)(set))->fd_count--; \
            break; \
        } \
    } \
  } while(fd == INVALID_SOCKET) /* always false */

  /* FD_SET do {} while(0) loop is always false. Squelch the warning. */
  #undef FD_SET
  #define FD_SET(fd, set) do { \
    if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) \
        ((fd_set FAR *)(set))->fd_array[((fd_set FAR *)(set))->fd_count++]=(fd);\
  } while(fd == INVALID_SOCKET) /* always false */

  #undef FAR
  #define FAR far
  #endif

  int w32sockInitialize(void);
  int w32sockDeinitialize(void);
  int w32sockIsAlive(void);
#else
  typedef int SOCKET;
  struct timeval { long tv_sec; long tv_usec; }; // seconds and microseconds

  int closesocket(SOCKET s);
  int send(SOCKET s,char *buff,int len,int flags);
  int recv(SOCKET s,char *buff,int len,int flags);

  #if defined(__WATCOMC__) //we can inline these suckers
    unsigned short ntohs( unsigned short );
    unsigned short htons( unsigned short );
    unsigned long ntohl( unsigned long );
    unsigned long htonl( unsigned long );
    #pragma aux htons = 0x86 0xc4 /* xchg al,ah */ \
                        parm [ax] value[ax] modify exact[ax]
    #pragma aux (htons) ntohs;  /* ntohs is identical to htons */
    #ifdef __386__
    #pragma aux htonl = 0x86 0xc4 0xc1 0xc0 0x10 0x86 0xc4 \
                        parm [eax] value[eax] modify exact[eax]
                     /* xchg al,ah  rol eax,16   xchg al,ah */
    #pragma aux (htonl) ntohl;  /* ntohl is identical to htonl */
    #else
    #define ntohl(x) ((((x)&0xff)<<24) | (((x)>>24)&0xff) | \
                      (((x)&0xff00)<<8) | (((x)>>8)&0xff00))
    #define htonl(x) ntohl(x)                      
    #endif
  #else
    #define ntohs(x) ((((x)&0xff)<<8) | (((x)>>8)&0xff))
    #define htons(x) ntohs(x)
    #define ntohl(x) ((((x)&0xff)<<24) | (((x)>>24)&0xff) | \
                      (((x)&0xff00)<<8) | (((x)>>8)&0xff00))
    #define htonl(x) ntohl(x)                      
  #endif

#endif
  
#endif //__W32SOCK_H__
