/* File:  courier.h - Last Edit:  */
/* arvani		Thu Feb  8 11:33:01 1990 */
/* Copyright (C) by Xerox Corporation, 1990.  All rights reserved. */
/** courier.h 1.2, last change 11/10/88 **/
/* $Header: courier.h,v 3.2 87/05/11 09:27:36 ed Exp $ */
/*
 $Log:	courier.h,v $
 * Revision 3.2  87/05/11  09:27:36  ed
 * Added MAX←SEQUENCE←LENGTH.
 * 
 * Revision 3.1  87/03/17  09:30:33  ed
 * changes from webster: Sequence←of←Unspecified, mc68xxx conditionals
 * 
 * Revision 3.1  87/03/17  09:30:33  ed
 * Added conditions for mc68000 family
 * 
 * Revision 3.0  87/01/14  14:40:39  ed
 * release containing Xerox (Webster Research Center) modifications
 * 
 * Revision 2.0  85/11/21  07:22:05  jqj
 * 4.3BSD standard release
 * 
 * Revision 1.3  85/10/23  16:43:30  root
 * Probably correct versions of basic conversion operators for the Gould.
 * 
 * Revision 1.2  85/10/21  12:49:15  root
 * Gould version:  definitions for MoveLong, etc. (the MoveLong routine is in misc.c)
 * 
 * Revision 1.2  85/10/17  16:46:55  jqj
 * first Gould version: definitions for MoveLong etc.
 * 
 * Revision 1.5  85/05/23  06:18:06  jqj
 * Public Beta-test version, released 24 May 1985
 * 
 * Revision 1.3  85/03/11  16:36:54  jqj
 * Public alpha-test version, released 11 March 1985
 * 
 * Revision 1.2  85/01/27  07:37:18  jqj
 * finished but undebugged version
 * 
 */

#ifndef COURIERVERSION
#define COURIERVERSION	3	/* the version of Courier we support */

/* Predefined Courier types */
typedef char		Boolean;
typedef unsigned short	Cardinal;
typedef unsigned long	LongCardinal;
typedef short		Integer;
typedef long		LongInteger;
typedef char		*String;
typedef unsigned short	Unspecified;
typedef unsigned long	LongUnspecified;
typedef int		NilRecord;
#ifndef ←COMMON←
typedef	int		(*pfi←t)();
#endif

/*
 * Low-level byte moving, with byte-swapping.
 * Use these definitions for VAX and other low-enders.
 */
#if vax || i80x86 || i386 || M←I286 || M←I86
#define externalize←Boolean(p, buf)	(*(short*)(buf) = *((char*)(p))<<8, 1)
#define internalize←Boolean(p, buf)	(*(char*)(p) = *((char*)(buf)+1), 1)
#define MoveShort(a, b)	(*(char*)(b) = *((char*)(a)+1),\
			 *((char*)(b)+1) = *(char*)(a),1)
#define MoveLong(a, b)	(*(char*)(b) = *((char*)(a)+3),\
			 *((char*)(b)+1) = *((char*)(a)+2),\
			 *((char*)(b)+2) = *((char*)(a)+1),\
			 *((char*)(b)+3) = *(char*)(a), 2)
#endif

/*
 * Low-level byte moving, without byte-swapping.
 * Use these definitions for SUN and other high-enders.
 */
#if sun || mc68000 || mc68010 || mc68020 || m68 || m68k || M68020 || sparc
#define externalize←Boolean(p, buf)  (*(Unspecified*)(buf) = 1&*(char*)(p), 1)
#define internalize←Boolean(p, buf)  (*(char*)(p) = 1&*(Unspecified*)(buf), 1)
#define MoveShort(a, b)	(*(short *)(b) = *(short *)(a),1)
#if sparc
#define MoveLong(a, b)	(*(short *)(b) = *((short *)(a)),\
			 *((short *)(b)+1) = *((short *)(a)+1), 2)
#else
#define MoveLong(a, b)	(*(long *)(b) = *(long *)(a),2)
#endif
#endif

/*
 * Low-level byte moving, without byte-swapping.
 * Use these definitions for sel and other high-enders that require
 * longword alignment.
 */
#if sel
#define externalize←Boolean(p, buf)  (*(Unspecified*)(buf) = 1&*(char*)(p), 1)
#define internalize←Boolean(p, buf)  (*(p) = 1&*(Unspecified*)(buf), 1)
#define MoveShort(a, b)	(*(short *)(b) = *(short *)(a),1)
int MoveLong();
#endif

/*
 * sizeof←Foo(p) is a function that returns the externalized size of
 * the variable specified as argument (assumed to be of type Foo).
 * clear←Foo(p) is a function that deallocates any components of Foo.
 * externalize←Foo translates a variable from C form to external
 * serialized form.
 * internalize←Foo translates a variable from external serializedform 
 * to internal C form
 */
#define sizeof←NilRecord(p)		0
#define clear←NilRecord(p)
#define externalize←NilRecord(p, buf)		0
#define internalize←NilRecord(p, buf)		0

#define sizeof←Boolean(p)		1
#define clear←Boolean(p)

#define sizeof←Cardinal(p)		1
#define clear←Cardinal(p)
#define externalize←Cardinal(p, buf)		MoveShort(p, buf)
#define internalize←Cardinal(p, buf)		MoveShort(buf, p)

#define sizeof←LongCardinal(p)		2
#define clear←LongCardinal(p)
#define externalize←LongCardinal(p, buf)	MoveLong(p, buf)
#define internalize←LongCardinal(p, buf)	MoveLong(buf, p)

#define sizeof←Integer(p)		1
#define clear←Integer(p)
#define externalize←Integer(p, buf)		MoveShort(p, buf)
#define internalize←Integer(p, buf)		MoveShort(buf, p)

#define sizeof←LongInteger(p)		2
#define clear←LongInteger(p)
#define externalize←LongInteger(p, buf)		MoveLong(p, buf)
#define internalize←LongInteger(p, buf)		MoveLong(buf, p)

#define sizeof←Unspecified(p)		1
#define clear←Unspecified(p)
#define externalize←Unspecified(p, buf)		MoveShort(p, buf)
#define internalize←Unspecified(p, buf)		MoveShort(buf, p)

#define sizeof←LongUnspecified(p)	2
#define clear←LongUnspecified(p)
#define externalize←LongUnspecified(p, buf)	MoveLong(p, buf)
#define internalize←LongUnspecified(p, buf)	MoveLong(buf, p)

#ifndef MAXWORDS
#define MAXWORDS 267
#endif

#ifndef SPPMAXDATA
#define SPPMAXDATA (MAXWORDS*2)
#endif

/* For streams */
typedef enum {
	nextSegment = 0,
	lastSegment = 1
} StreamEnumerator;
#define sizeof←StreamEnumerator sizeof←enumeration
#define clear←StreamEnumerator clear←enumeration
#define externalize←StreamEnumerator externalize←enumeration
#define internalize←StreamEnumerator internalize←enumeration

/* miscellaneous structures and values used by Courier runtimes */
#ifdef BSD
/*
 * define Berkeley specific COURIERFD
 */
#define COURIERFD int*

#else
/*
 * define System V (Mentat) specific COURIERFD
 */
#define COURIERFD int

#endif
 
#define MAX←SEQUENCE←LENGTH	65535

typedef struct {
	Cardinal length;
	Unspecified *sequence;
} Sequence←of←Unspecified;

/* 
 * message types for Courier messages
 * (should only be of interest to the runtimes)
 */
#define CALL	0
#define REJECT	1
#define RETURN	2
#define ABORT	3

/* components of Courier error messages */
typedef struct {
	Cardinal lowest;
	Cardinal highest;
} ImplementedVersionNumbers;

typedef struct {
	enum {
		unspecifiedError = 65535,
		invalidArgument = 3,
		noSuchProcedureValue = 2,
		noSuchVersionNumber = 1,
		noSuchProgramNumber = 0
	} designator;
	union {
		NilRecord u←noSuchProgramNumber;
#define noSuchProgramNumber←case u.u←noSuchProgramNumber
		ImplementedVersionNumbers u←noSuchVersionNumber;
#define noSuchVersionNumber←case u.u←noSuchVersionNumber
		NilRecord u←noSuchProcedureValue;
#define noSuchProcedureValue←case u.u←noSuchProcedureValue
		NilRecord u←invalidArgument;
#define invalidArgument←case u.u←invalidArgument
		NilRecord u←unspecifiedError;
#define unspecifiedError←case u.u←unspecifiedError
	} u;
} rejectionDetails;

/* Macro for unpacking error arguments given a typedef and a field name */
#define CourierErrArgs(type,field) \
	(((type *)Exception.Message)->field)

/* miscellaneous constants */
#ifndef TRUE
#define TRUE (1)
#endif

#ifndef FALSE
#define FALSE (0)
#endif

#ifndef NULL
#define NULL ((char*) 0)
#endif

/* return values for Bulk Data routines */
#define	BDT←WRITE←ABORT		1
#define	BDT←WRITE←FINISHED	2
#define	BDT←READ←ABORT		3
#define	BDT←READ←FINISHED	4

/* exceptions defined in Courier */
#define REJECT←ERROR		65535
#define SYSTEM←ERROR		65534
#define PROTOCOL←VIOLATION	65533

/* External declarations */
extern	Unspecified	* Allocate();
extern	void		cour←finish←bdt();
extern	Unspecified	* cour←get←ret();
extern	int		cour←send←call();
extern	Unspecified	* cour←send←call←get←ret();
extern	COURIERFD	cour←establish←conn();
extern	int		cour←close←conn();

/* Address types */
#define	COUR←DEF←ADDR←TYPE	1
#define	COUR←ISO←ADDR←TYPE	2
#define	COUR←TCP←ADDR←TYPE	3
#define	COUR←XNS←ADDR←TYPE	4

typedef struct cour←err←report←s {
	int	cer←tag;
	int	cer←size;
	pfi←t	cer←internalize;
} COUR←ERR←REPORT;

#include <courier/os←port.h>

#endif