Milán Major

netscape-revival

1 branch
Code

sun-java/netscape/net/nsn.h

/*
 * @(#)nsn.h	1.2 95/06/14 Warren Harris
 *
 * Copyright (c) 1995 Netscape Communications Corporation. All Rights Reserved.
 *
 */

#ifndef _NSN_H_
#define _NSN_H_

#include "java.h"
#include "xp.h"
#include "net.h"
#include "java.h"

/******************************************************************************/

#ifdef DEBUG
#define NSN_CLEAR(x)	do { if (x) { XP_MEMSET(x, 0x01, sizeof(*(x))); }} while (0)
#else
#define NSN_CLEAR(x)	
#endif

#define NSN_FREE(x)	do { NSN_CLEAR(x); free(x); } while (0)
#define NSN_FREEIF(x)	if ((x) != NULL) NSN_FREE(x)

#undef  MAX
#define MAX(x, y)	(((x) > (y)) ? (x) : (y))

/******************************************************************************/

typedef struct nsn_DataQueueElement {
    struct nsn_DataQueueElement*	next;
    char*				data;
    int32				dataLength;
    int32				readCursor;
    int32				writeCursor;
} nsn_DataQueueElement;

typedef struct nsn_DataQueue {
    nsn_DataQueueElement*	head;
    nsn_DataQueueElement*	tail;
} nsn_DataQueue;

extern void
nsn_DataQueue_insert(nsn_DataQueue* queue, nsn_DataQueueElement* buf);

extern nsn_DataQueueElement*
nsn_DataQueue_writeBytes(nsn_DataQueue* queue, const char* bytes, long length);

/* Returns the amount actually read: */
extern long
nsn_DataQueue_readBytes(nsn_DataQueue* queue, char* intoBuf, long bufLen);

extern long
nsn_DataQueue_length(nsn_DataQueue* queue);

extern void
nsn_DataQueue_clear(nsn_DataQueue* queue);

/******************************************************************************/

typedef enum nsn_JavaStreamState {
    OPENING,	/* just created */
    POSTING,	/* accumulating data to post (opened for output) */
    OPENED,	/* opened for input */
    JAVA_DONE,	/* java's closed the stream, and netlib should clean it up */
    LIBNET_DONE,/* netlib closed the stream, and java should clean it up */
    CLOSED	/* really closed */
} nsn_JavaStreamState;

/* The JavaStreamData struct is protected by the monitor it contains. It is
   illegal to access any field of this struct without first entering the 
   monitor. */
typedef struct nsn_JavaStreamData {
    nsn_JavaStreamState	state;
    URL_Struct*		url;
    MWContext*		javaContext;
    MWContext*		realContext;
    NET_StreamClass*	netStream;
    nsn_DataQueue	dataQueue;
    int			refcount;
    int			notifies;
    int			errorStatus;
    char*		errorMessage;
} nsn_JavaStreamData;

/*
** Let the JavaStreamData structure be the key to the monitor cache:
*/
#define nsn_JavaStream_monitor(javaData)	((uint32)javaData)

/*
** This method is called whenever netlib initiates the closing of a
** connection.
*/
extern void
nsn_JavaStream_abort(nsn_JavaStreamData* javaData, int status);

/*
** This method is called whenever java initiates the closing of a
** connection.
*/
extern void
nsn_JavaStream_javaClose(nsn_JavaStreamData* javaData);

/*
** This method is called whenever both sides have decided to close.  It
** destroys the JavaStreamData's internal state.
*/
extern void
nsn_JavaStream_close(nsn_JavaStreamData* javaData);

/*
** This method is called to install a tickle hook for certain network
** calls on the mac to avoid deadlock.
*/

typedef int (* nsn_TickleHookProcPtr)(void);

extern void 
nsn_InstallTickleHookProc(nsn_TickleHookProcPtr newProc);

/******************************************************************************/

extern MWContext*
nsn_GetCurrentContext(void);

extern LJAppletData*
nsn_GetCurrentAppletData(void);

extern MWContext*
nsn_JavaContext_make(URL_Struct* url, struct nsn_JavaStreamData* javaData);

extern void
nsn_JavaContext_destroy(MWContext* context);

/******************************************************************************/
/* Message formatting things */
 
#define FIX_NULL(s)		(s == NULL ? "<null>" : s)

#define URL_ADDR(javaData)	((javaData)->url ? (javaData)->url->address : "?")

/******************************************************************************/
/*
** Helpful macros for entering and exiting native functions while
** synchronizing on the javaData structure. These macros assume there is
** a structure named javaData
*/

#define ENTER_METHOD(message, unconnectedAction)	  \
{							  \
    if (javaData == NULL) { unconnectedAction; }	  \
    monitorEnter(nsn_JavaStream_monitor(javaData));	  \
    PR_LOG_BEGIN(NSJAVA, debug,				  \
		 (message "(%s)\n", URL_ADDR(javaData))); \
    {							  \

/* Possible unconnectedActions: */
#define SILENTLY_FAIL					  \
    goto doneWithMethod;				  \

#define IO_EXCEPTION					  \
    SignalError(0, "java/io/IOException",		  \
		"connnection not established");		  \
    goto doneWithMethod;				  \

#define CANT_HAPPEN					  \
    PR_ASSERT(javaData != NULL);			  \
    goto doneWithMethod;	/* for non-debug */	  \

#define EXIT_METHOD(message)				  \
        ; /* in case there's a label before the macro */  \
    }							  \
    PR_LOG_END(NSJAVA, debug,				  \
	       (message "(%s)\n", URL_ADDR(javaData)));	  \
    monitorExit(nsn_JavaStream_monitor(javaData));	  \
  doneWithMethod: ;					  \
}							  \

/******************************************************************************/

#ifdef DEBUG

/*
** These counters are used to keep track of whether we're freeing all the
** objects we're creating:
*/
typedef struct nsn_Counters {
    int javaDataCount;
    int urlCount;
    int contextCount;
    int streamCount;
    int bufCount;
} nsn_Counters;

extern nsn_Counters nsnCounters;

#define INCR(counter)	(nsnCounters.counter++)
#define DECR(counter)	(nsnCounters.counter--)

#else

#define INCR(counter)	((void)0)
#define DECR(counter)	((void)0)

#endif /* DEBUG */

/******************************************************************************/

#endif /* _NSN_H_ */