project_files/Android-build/SDL-android-project/jni/sdl_net/SDLnetselect.c
branchhedgeroid
changeset 5317 86984c1034a5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/jni/sdl_net/SDLnetselect.c	Thu Jun 23 14:30:04 2011 +0200
@@ -0,0 +1,226 @@
+/*
+    SDL_net:  An example cross-platform network library for use with SDL
+    Copyright (C) 1997-2004 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+/* $Id: SDLnetselect.c 1192 2004-01-04 17:41:55Z slouken $ */
+
+#include "SDLnetsys.h"
+#include "SDL_net.h"
+
+/* The select() API for network sockets */
+
+struct SDLNet_Socket {
+	int ready;
+	SOCKET channel;
+#ifdef MACOS_OPENTRANSPORT
+	OTEventCode curEvent;
+#endif
+};
+
+struct _SDLNet_SocketSet {
+	int numsockets;
+	int maxsockets;
+	struct SDLNet_Socket **sockets;
+};
+
+/* Allocate a socket set for use with SDLNet_CheckSockets() 
+   This returns a socket set for up to 'maxsockets' sockets, or NULL if 
+   the function ran out of memory. 
+ */
+SDLNet_SocketSet SDLNet_AllocSocketSet(int maxsockets)
+{
+	struct _SDLNet_SocketSet *set;
+	int i;
+
+	set = (struct _SDLNet_SocketSet *)malloc(sizeof(*set));
+	if ( set != NULL ) {
+		set->numsockets = 0;
+		set->maxsockets = maxsockets;
+		set->sockets = (struct SDLNet_Socket **)malloc
+					(maxsockets*sizeof(*set->sockets));
+		if ( set->sockets != NULL ) {
+			for ( i=0; i<maxsockets; ++i ) {
+				set->sockets[i] = NULL;
+			}
+		} else {
+			free(set);
+			set = NULL;
+		}
+	}
+	return(set);
+}
+
+/* Add a socket to a set of sockets to be checked for available data */
+int SDLNet_AddSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock)
+{
+	if ( sock != NULL ) {
+		if ( set->numsockets == set->maxsockets ) {
+			SDLNet_SetError("socketset is full");
+			return(-1);
+		}
+		set->sockets[set->numsockets++] = (struct SDLNet_Socket *)sock;
+	}
+	return(set->numsockets);
+}
+
+/* Remove a socket from a set of sockets to be checked for available data */
+int SDLNet_DelSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock)
+{
+	int i;
+
+	if ( sock != NULL ) {
+		for ( i=0; i<set->numsockets; ++i ) {
+			if ( set->sockets[i] == (struct SDLNet_Socket *)sock ) {
+				break;
+			}
+		}
+		if ( i == set->numsockets ) {
+			SDLNet_SetError("socket not found in socketset");
+			return(-1);
+		}
+		--set->numsockets;
+		for ( ; i<set->numsockets; ++i ) {
+			set->sockets[i] = set->sockets[i+1];
+		}
+	}
+	return(set->numsockets);
+}
+
+/* This function checks to see if data is available for reading on the
+   given set of sockets.  If 'timeout' is 0, it performs a quick poll,
+   otherwise the function returns when either data is available for
+   reading, or the timeout in milliseconds has elapsed, which ever occurs
+   first.  This function returns the number of sockets ready for reading,
+   or -1 if there was an error with the select() system call.
+*/
+#ifdef MACOS_OPENTRANSPORT
+int SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout)
+{
+Uint32	stop;
+int 	numReady;
+
+	/* Loop, polling the network devices */
+	
+	stop = SDL_GetTicks() + timeout;
+	
+	do 
+	{
+	OTResult status;
+	size_t	numBytes;
+	int 	i;
+		
+		numReady = 0;
+	
+		for (i = set->numsockets-1;i >= 0;--i) 
+		{
+			status = OTLook( set->sockets[i]->channel );
+			if( status > 0 )
+			{
+				switch( status )
+				{
+					case T_UDERR:
+						OTRcvUDErr( set->sockets[i]->channel , nil);
+						break;
+					case T_DISCONNECT:
+						OTRcvDisconnect( set->sockets[i]->channel, nil );
+						break;
+					case T_ORDREL:
+						OTRcvOrderlyDisconnect(set->sockets[i]->channel );
+						break;
+					case T_CONNECT:
+						OTRcvConnect( set->sockets[i]->channel, nil );
+						break;
+					
+				
+					default:
+						set->sockets[i]->ready = 1;
+						++numReady;
+				}
+			}
+			else if( OTCountDataBytes(set->sockets[i]->channel, &numBytes ) != kOTNoDataErr )
+			{
+				set->sockets[i]->ready = 1;
+				++numReady;
+			}
+			else
+				set->sockets[i]->ready = 0;
+		}
+		
+	} while (!numReady && (SDL_GetTicks() < stop));
+
+	return(numReady);
+}
+#else
+int SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout)
+{
+	int i;
+	SOCKET maxfd;
+	int retval;
+	struct timeval tv;
+	fd_set mask;
+
+	/* Find the largest file descriptor */
+	maxfd = 0;
+	for ( i=set->numsockets-1; i>=0; --i ) {
+		if ( set->sockets[i]->channel > maxfd ) {
+			maxfd = set->sockets[i]->channel;
+		}
+	}
+
+	/* Check the file descriptors for available data */
+	do {
+		errno = 0;
+
+		/* Set up the mask of file descriptors */
+		FD_ZERO(&mask);
+		for ( i=set->numsockets-1; i>=0; --i ) {
+			FD_SET(set->sockets[i]->channel, &mask);
+		}
+
+		/* Set up the timeout */
+		tv.tv_sec = timeout/1000;
+		tv.tv_usec = (timeout%1000)*1000;
+
+		/* Look! */
+		retval = select(maxfd+1, &mask, NULL, NULL, &tv);
+	} while ( errno == EINTR );
+
+	/* Mark all file descriptors ready that have data available */
+	if ( retval > 0 ) {
+		for ( i=set->numsockets-1; i>=0; --i ) {
+			if ( FD_ISSET(set->sockets[i]->channel, &mask) ) {
+				set->sockets[i]->ready = 1;
+			}
+		}
+	}
+	return(retval);
+}
+#endif /* MACOS_OPENTRANSPORT */
+   
+/* Free a set of sockets allocated by SDL_NetAllocSocketSet() */
+extern void SDLNet_FreeSocketSet(SDLNet_SocketSet set)
+{
+	if ( set ) {
+		free(set->sockets);
+		free(set);
+	}
+}
+