Milán Major

netscape-revival

1 branch
Code

lib/mac/macsock/src/sockets.h

#pragma once
// sockets.h
#include "CNetwork.h"
#include "macsock.h"
#include <PP_Types.h>
#include <errno.h>
class CNetStream;
class CDNSObject;
class MacTCPDriver;

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

/*************************************************************************************
 * MacSocket
 * Encapsulates operations on individual sockets, and socket table management
 * Sockets operate on top of tcp streams
 *************************************************************************************/
class MacSocket	{
public:
// ¥¥ static

	// Creates a new socket. Sets errno
	static Int16 CreateSocket(int domain, int type, int protocol);
	// Use in socket routines to return an error instead of errno = ENOBUF, return -1
	static int   SocketError(int err) {errno = err; return err == 0 ? 0 : -1;}
	// Socket table
	static MacSocket*	GetSocket(int socketID) { return (((socketID < MAX_SOCKETS) && (socketID >= 0))? 
													sSockets[socketID] : NULL);};

// ¥¥ constructors
	
	MacSocket(Int16 index, int type);	// Index is pointer to a free place in the socket table
	~MacSocket();			// Never use delete. Call Destroy

// ¥¥ Netscape select mechanism
	void SetReadSelect() {fReadSelect = TRUE;};
	void ClearReadSelect() {fReadSelect = FALSE;};
	void SetConnectSelect() {fConnectSelect = TRUE;};
	void ClearConnectSelect() {fConnectSelect = FALSE;};
	
// ¥¥ DNS lookups
	int StartAsyncDNSLookup(char * hostName, struct hostent ** hoststruct_ptr_ptr);
	void ClearDNSSelect();
	void SetDNSLookupObject(CDNSObject * dns);

// ¥¥ sock routines interface
	int Create();
	int Destroy(Boolean doAbort);
	int Connect(InetHost host, InetPort port);
	int Accept(InetHost &host, InetPort &port);
	int Bind(InetHost host, InetPort port);
	int Listen(int backlog);
	int Write (const void * buffer, unsigned int buflen); 
	int Read (void * buffer, unsigned int buflen);
	
	int SetBlocking(Boolean blocking);	// Are we a blocking socket?
	int SetSocketOption(int level, int optname, const void *optval);
	int SocketAvailable(size_t& bytesAvailable);
	Boolean Select(Boolean& readReady,Boolean& writeReady,Boolean& exceptReady);
	int GetPeerName(InetHost& host, InetPort& port);
	int GetSockName(InetHost& host, InetPort& port);
	int SendTo(const void *msg, int len, int flags, InetHost host, InetPort port);
	int ReceiveFrom(void *buffer, int len, int flags, struct sockaddr *from, int& fromLen);
	int UDPSendTo(const void *msg, int len, int flags, InetHost host, InetPort port);
	int UDPReceiveFrom(void *buffer, int len, int flags, struct sockaddr *from, int& fromLen);
// ¥¥ stream notifications
	void HadClosingException();
	void HadOpenExcetion();
	void ConnectComplete(Boolean isListen, OSStatus err);
	void AcceptComplete(OSStatus err);
// ¥¥Êselect mechanism, callbacks from streams
	void ReadNotify() {fReadReady = TRUE;};
	void WriteComplete(int err);
	void CloseNotify() {fCloseException = TRUE;};
	void DNSNotify() {fDNSException = TRUE;};

	int					fType;					// Type of socket (stream, udp)

private:
	static MacSocket* sSockets[MAX_SOCKETS];
	
	Int16			fIndex;
	CNetStream *	fStream;
	Boolean			fReadReady;
	Boolean			fConnectException, 	// Exception flags. Set after these operations are completed
					fCloseException,
					fDNSException,
					fListenException;
	UInt32			fSerialNumber;		// This socketÕs ID
// Streams and sockets deal with return of the connect/listen call differently
// With streams, you make the call once, and wait for the async return
// With sockets, you make the same call repeatedly, and wait for it to return failure
// This behaviour is abstracted in sockets
	enum ConnectStatus	{ 
		eIdle, 
		
		eConnectInProgress, 	// After calling connect
		eConnectSuccess,
		eConnectFailed,
		eConnected,
		
		eListenInProgress, 		// After calling listen
		eListenSuccess,
		eListenFailed,
		eAcceptInProgress,
		eAcceptSuccess,
		eAcceptFailed
	};

	ConnectStatus fConnectStatus;

	CDNSObject * 		fDNSLookup;				// DNS lookup object
	friend class 		CNetStream;
	friend class 		MacTCPDriver;
	friend class 		OTDriver;
	Boolean 			fBlocking;				// Blocking socket?
	Boolean				fConnectSelect, fReadSelect;
	int					fWriteStatus;			// Are we done yet 0 = done, 1 in progress, <0 error done
	int					fOutstandingWrites;
	static				Boolean		sNotified;	// Do any sockets have notifications
	static 	UInt32 		sCurrentSerialNumber;	// The current ID we should use.
	
};