/*
** Copyright (c) 1991-1995 Xerox Corporation.  All Rights Reserved.
**
** Unlimited use, reproduction, and distribution of this software is
** permitted.  Any copy of this software must include both the above
** copyright notice of Xerox Corporation and this paragraph.  Any
** distribution of this software must comply with all applicable United
** States export control laws.  This software is made available AS IS,
** and XEROX CORPORATION DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
** INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY
** AND FITNESS FOR A PARTICULAR PURPOSE, AND NOTWITHSTANDING ANY OTHER
** PROVISION CONTAINED HEREIN, ANY LIABILITY FOR DAMAGES RESULTING FROM
** THE SOFTWARE OR ITS USE IS EXPRESSLY DISCLAIMED, WHETHER ARISING IN
** CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, EVEN IF
** XEROX CORPORATION IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
/* $Id: iluchdrs.h,v 1.79 1996/04/03 05:35:18 spreitze Exp $ */
/* Last edited by Mike Spreitzer April 2, 1996 12:53 pm PST */

#ifndef __ilu_c_h_
#define __ilu_c_h_

#include <iluxport.h>

#define OPTIONAL(x)	x
#define PASS(x)		x
#define RETAIN(x)	x
#define GLOBAL(x)	x
 
/* Note:  Things beginning with "ilu_" are exported from the ILU kernel,
          things beginning with "ILU_C_" are from the ILU ANSI C runtime
          for application use, and things beginning with "_ILU_C_" are
	  exported for use only by automatically generated code. */

/*==================================================*/
/*==================================================*/
/*           For internal use                       */
/*==================================================*/
/*==================================================*/

/* 
** C class implementation 
** the C class table(s) are
** generated by the stubber
** and represent the class
** and method heirarchy. each
** class iindicated in isl
** generates a class structure.
** the class structure ILU_C_Class
** contains a pointer to the
** ilu_Class and an array of 
** methods. 
*/

/*
** stub internal needs
*/

typedef struct CCls {
    ilu_Class   c;
    void (*methods[1])();
} _ILU_C_MethodBlock;
 
typedef _ILU_C_MethodBlock **ILU_C_Type;

typedef struct {
  ILU_C_Type	type;
  ilu_Server	server;
  ilu_Object	instanceId;
  void *	data;
  struct ILU_C_InterruptHandle_s *interruptH;
} ILU_C_Object;

typedef struct {
    unsigned long	_maximum;
    unsigned long	_length;
    char		*_buffer;
} ILU_C_Sequence_s, *ILU_C_Sequence;

typedef ilu_Exception	ILU_C_ExceptionCode;

typedef ilu_cardinal (*ILU_C_SizeFn) (ilu_Call c, void *p, ilu_Error * e);
/* <c_parameter_type(t, In)> p */

typedef void    (*ILU_C_OutputFn) (ilu_Call c, void *p, ilu_Error * e);
/* <c_parameter_type(t, In)> p */

typedef void   *(*ILU_C_InputFn) (ilu_Call c, void *p, ilu_Error * e);
/* <c_parameter_type(t, InOut)> p;
   <c_role_type(type, role_InpRet, FALSE)> returned */

typedef void    (*ILU_C_FreeFn) (void *p);
/* <c_role_type(type, role_Exn, FALSE)> p*/

typedef struct _ILU_C_ExceptionDescription_s {
  unsigned int    size;
  ilu_Class       class;
  ILU_C_SizeFn    sizeFn;
  ILU_C_OutputFn  outFn;
  ILU_C_InputFn   inFn;
  ILU_C_FreeFn    freeFn;
}              *_ILU_C_ExceptionDescription;

typedef struct _ILU_C_ObjectTable_struct * ILU_C_ObjectTable;

/* provide functions from ilu.isl directly */
typedef char * ilu_CString;

ILU_PUBLIC ilu_cardinal _ilu_CString__SizeOf (ilu_Call, ilu_CString, ilu_Error *);
ILU_PUBLIC ilu_CString _ilu_CString__Input (ilu_Call, ilu_CString *, ilu_Error *);
ILU_PUBLIC void _ilu_CString__Output (ilu_Call, ilu_CString, ilu_Error *);
ILU_PUBLIC void ilu_CString__Free (ilu_CString *);

/*==================================================*/
/*==================================================*/
/*          CORBA-specified interface               */
/*==================================================*/
/*==================================================*/

/* Main invariant holds; L2 otherwise unconstrained */

typedef ilu_integer		CORBA_long;
typedef ilu_shortinteger	CORBA_short;
typedef ilu_cardinal		CORBA_unsigned_long;
typedef ilu_shortcardinal	CORBA_unsigned_short;
typedef ilu_shortreal		CORBA_float;		
typedef ilu_real		CORBA_double;
typedef ilu_shortcharacter	CORBA_char;
typedef ilu_byte		CORBA_octet;
typedef unsigned char		CORBA_boolean;
typedef ilu_cardinal		CORBA_enum;
typedef CORBA_char *		CORBA_string;
typedef ILU_C_Object *		CORBA_Object;
		
#define CORBA_OBJECT_NIL	((CORBA_Object)0)

typedef enum { CORBA_NO_EXCEPTION, CORBA_USER_EXCEPTION, CORBA_SYSTEM_EXCEPTION } CORBA_exception_type;
typedef enum { CORBA_COMPLETED_YES, CORBA_COMPLETED_NO, CORBA_COMPLETED_MAYBE } CORBA_completion_status;

typedef struct _Environment_s {
  CORBA_exception_type	_major;
  ILU_C_ExceptionCode	returnCode;
  void			*ptr;
  ILU_C_FreeFn		freeRoutine;	/* called to free subsidiary storage, if any */
  ilu_Passport		callerPassport;
} CORBA_Environment;

typedef struct {
  unsigned long minor;
  CORBA_completion_status completed;
} CORBA_ex_body;

ILU_PUBLIC void		CORBA_exception_free( CORBA_Environment * );
ILU_PUBLIC char *	CORBA_exception_id( CORBA_Environment * );
ILU_PUBLIC void *	CORBA_exception_value( CORBA_Environment * );

ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_UNKNOWN;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_BAD_PARAM;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_NO_MEMORY;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_IMP_LIMIT;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_COMM_FAILURE;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_INV_OBJREF;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_NO_PERMISSION;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_INTERNAL;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_MARSHAL;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_INITIALIZE;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_NO_IMPLEMENT;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_BAD_TYPECODE;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_BAD_OPERATION;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_NO_RESOURCES;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_NO_RESPONSE;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_PERSIST_STORE;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_BAD_INV_ORDER;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_TRANSIENT;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_FREE_MEM;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_INV_IDENT;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_INV_FLAG;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_INTF_REPOS;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_BAD_CONTEXT;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_OBJ_ADAPTER;
ILU_PUBLIC ILU_C_ExceptionCode	ex_CORBA_DATA_CONVERSION;

/* ORB operations */

typedef void		CORBA_ORBStatus;
typedef void *		CORBA_Context;

ILU_PUBLIC CORBA_Object ILU_C_ORB;	/* should be first parameter to any ORB operation */

ILU_PUBLIC char *		CORBA_ORB_object_to_string (CORBA_Object theORB, CORBA_Object, CORBA_Environment *);
ILU_PUBLIC CORBA_Object		CORBA_ORB_string_to_object (CORBA_Object theORB, char *, CORBA_Environment * );
ILU_PUBLIC CORBA_ORBStatus	CORBA_ORB_get_default_context (CORBA_Object theORB, CORBA_Context *, CORBA_Environment*);

ILU_PUBLIC char *		CORBA_string_alloc (CORBA_unsigned_long len);
ILU_PUBLIC void			CORBA_free (void *);	/* free returned storage with this */

/* pre-defined basic type operations */
ILU_PUBLIC CORBA_octet *		CORBA_sequence_octet_bufalloc (CORBA_unsigned_long);
ILU_PUBLIC CORBA_boolean *		CORBA_sequence_boolean_bufalloc (CORBA_unsigned_long);
ILU_PUBLIC CORBA_char *		CORBA_sequence_char_bufalloc (CORBA_unsigned_long);
ILU_PUBLIC CORBA_unsigned_short *	CORBA_sequence_unsigned_short_bufalloc (CORBA_unsigned_long);
ILU_PUBLIC CORBA_unsigned_long *	CORBA_sequence_unsigned_long_bufalloc (CORBA_unsigned_long);
ILU_PUBLIC CORBA_short *		CORBA_sequence_short_bufalloc (CORBA_unsigned_long);
ILU_PUBLIC CORBA_long *		CORBA_sequence_long_bufalloc (CORBA_unsigned_long);
ILU_PUBLIC CORBA_float *		CORBA_sequence_float_bufalloc (CORBA_unsigned_long);
ILU_PUBLIC CORBA_double *		CORBA_sequence_double_bufalloc (CORBA_unsigned_long);
ILU_PUBLIC CORBA_string *		CORBA_sequence_string_bufalloc (CORBA_unsigned_long);

/* Object operations */
ILU_PUBLIC CORBA_boolean	CORBA_Object_is_nil (CORBA_Object, CORBA_Environment *);
ILU_PUBLIC CORBA_Object		CORBA_Object_duplicate (CORBA_Object, CORBA_Environment *);
ILU_PUBLIC void	 		CORBA_Object_release( CORBA_Object, CORBA_Environment * );

/* Main invariant holds */
ILU_PUBLIC void		_ILU_C_SetProtocolError (CORBA_Environment *, ilu_ProtocolException);

#define ILU_C_OBJECT		CORBA_Object
#define ILU_C_ENVIRONMENT	CORBA_Environment
#define ILU_C_SUCCESSFUL(s)	((s)->_major == CORBA_NO_EXCEPTION)
#define ILU_C_SET_SUCCESSFUL(s)	((s)->_major = CORBA_NO_EXCEPTION)
#define ILU_C_NO_EXCEPTION	CORBA_NO_EXCEPTION
#define ILU_C_USER_EXCEPTION	CORBA_USER_EXCEPTION
#define ILU_C_SYSTEM_EXCEPTION	CORBA_SYSTEM_EXCEPTION
#define ILU_C_EXCEPTION_ID(e)	CORBA_exception_id(e)
#define ILU_C_EXCEPTION_FREE(e)	CORBA_exception_free(e)
#define ILU_C_EXCEPTION_VALUE(e) CORBA_exception_value(e)
#define ILU_C_SYSEXN_BODY	CORBA_ex_body
#define ILU_C_COMPLETION(st)	(CORBA_COMPLETED_##st)
#define ILU_C_COMPLETIONSTATUS	CORBA_completion_status

#define ILU_C_STDEX(ename) (ex_CORBA_##ename)

#define ILU_C_RAISE_SYSTEM(p,ename,mcode,ccode) \
ILU_C_RAISE_SYS_EXPR(p,ILU_C_STDEX(ename),mcode,ILU_C_COMPLETION(ccode))

#define ILU_C_RAISE_SYS_EXPR(p,exn,mcode,cmpln) \
	((p)->_major = ILU_C_SYSTEM_EXCEPTION, \
	 (p)->returnCode = (exn), \
	 (p)->ptr = (void*)ilu_malloc(sizeof(ILU_C_SYSEXN_BODY)), \
	 ((ILU_C_SYSEXN_BODY *)((p)->ptr))->minor = (mcode), \
	 ((ILU_C_SYSEXN_BODY *)((p)->ptr))->completed = (cmpln), \
	 (p)->freeRoutine = (void (*)(void *)) 0, (p))

/*==================================================*/
/*==================================================*/
/*                   ILU-specific stuff             */
/*               for application developers         */
/*==================================================*/
/*==================================================*/

/*==== Types =======================================*/

/*L1_sup < otmu*/
/*L2 unconstrained*/
ILU_PUBLIC ilu_Class	ILU_C_FindILUClassByTypeName ( ilu_string classname );

/*L1_sup < otmu*/
/*L2 unconstrained*/
ILU_PUBLIC ilu_Class	ILU_C_FindILUClassByTypeID ( ilu_string class_unique_id );

/* Locking unconstrained */
ILU_PUBLIC GLOBAL(OPTIONAL(ilu_string))	ILU_C_ClassName ( RETAIN(ILU_C_Object *) );

/* Locking unconstrained */
ILU_PUBLIC GLOBAL(OPTIONAL(ilu_string))	ILU_C_ClassID ( RETAIN(ILU_C_Object *) );

/* locking Unrestricted */
ILU_PUBLIC ilu_Class	ILU_C_ClassRecordOfInstance (ILU_C_Object *o);	/* returns typecode for object */

/* Unrestricted */
ILU_PUBLIC          PASS(char *) ILU_C_Strdup(RETAIN(char *str));

/*==== Object manipulation =========================*/

/*
 * In all of these, the Main Invariant should hold, and L2 is
 * otherwise unrestricted
 */

ILU_PUBLIC ilu_string	ILU_C_SBHOfObject ( ILU_C_Object * obj );
/*
 * given an object, returns a string form which is its name and
 * contact information
 */

#ifdef IIOP_PROTOCOL

ILU_PUBLIC ilu_string	ILU_C_IOROfObject ( ILU_C_Object * obj );
/*
 * given an object, returns a string form which is its name and
 * contact information, as specified by the CORBA IIOP spec.
 */

#endif

ILU_PUBLIC ILU_C_Object   *
  ILU_C_SBHToObject(char *sbh,
		    ilu_Class static_type,
		    ILU_C_ENVIRONMENT * env);
/*
 * Takes an object reference and returns the object.  static_type is
 * a type the caller knows the object to have.
 */

ILU_PUBLIC void
  ILU_C_PingObject(ILU_C_OBJECT obj, ILU_C_ENVIRONMENT * env);
/* May raise a standard exception. */

ILU_PUBLIC void
  ILU_C_DestroyObject(ILU_C_OBJECT  obj);
/* Ensure this C object has no associated kernel object. */

ILU_PUBLIC void
  ILU_C_CloseServer(ilu_Server s,
		    ilu_cardinal * ncobjs, ilu_cardinal * nviobjs,
		    ilu_cardinal * nconns, ILU_C_ENVIRONMENT * env);
/*
 * Shuts down the given server, destroying all objects currently
 * reified in the server.  Stores some approximate statistics
 * through the last three parameters if they're (individually) not
 * NIL.  *ncobjs gets the number of ILU_C_OBJECTs that were reified
 * in the server at the start of this operation; *nviobjs gets the
 * numer of kernel objects in which the kernel remains very
 * interested; *nconns gets the number of connections (of that
 * server) whose I/O mutex is held.  These sums are only
 * approximate because the server's mutex is released and
 * re-acquired for every object destruction, so things could
 * (depending on the application) change during the process.
 */

ILU_PUBLIC void
  ILU_C_DestroyObjectAndServer(ILU_C_OBJECT obj,
			       ILU_C_ENVIRONMENT * env);
/* ILU_C_DestroyObject then ILU_C_CloseServer(s, NIL, NIL, NIL, env). */

ILU_PUBLIC          ilu_boolean
  ILU_C_ValidateOrDestroyObjSvr(ILU_C_OBJECT obj,
				ILU_C_ENVIRONMENT * env);
/*
 * Calls ILU_C_PingObject, and then ILU_C_DestroyObjectAndServer if
 * the ping suggests obj's server is unreachable.  Standard
 * exceptions suggesting the server is unreachable don't go into
 * *env; internal failures do.  Returns true if ping succeeds,
 * false if DestroyObjectAndServer called.
 */

/* Main invariant holds */
ILU_PUBLIC ILU_C_Object *
  ILU_C_CreateSurrogateObject (ilu_Class class,
			       RETAIN(ilu_string) ih,
			       ilu_Server server,
			       ILU_C_ENVIRONMENT *env);
/* Create and return an instance of the specified class,
   with the specified ih, on the specified server */

/*==== Interrupting Calls =========================*/
/* Main Invariant holds; L2 not further restricted */

/* When the runtime is single-threaded, use the following facilities
to interrupt calls.  When the runtime is multi-threaded, interrupt a call by doing the normal thing to interrupt a thread's execution. */

typedef struct ILU_C_InterruptHandle_s *ILU_C_InterruptHandle;

ILU_PUBLIC ILU_C_InterruptHandle ILU_C_NewInterruptHandle(void);
/* An interruption scope.  Returns NIL if can't allocate. */

ILU_PUBLIC void 
ILU_C_SetObjectInterruptHandle(ILU_C_Object * obj,
			       ILU_C_InterruptHandle h);
/*
 * Associate h with obj henceforth; overrides the previous
 * association for obj, if any.  Pass h=NIL to remove previous
 * association, if any.  No-op if obj is a true object.
 */

ILU_PUBLIC void ILU_C_InterruptHandleCalls(ILU_C_InterruptHandle h);
/* Interrupt current RPCs on objects currently associated with h. */


/*==== Simple Binding =========================*/

/*
 * In all of these, the Main Invariant should hold, and L2 is
 * otherwise unrestricted
 */

ILU_PUBLIC OPTIONAL(PASS(char *))
     ILU_C_PublishObject ( ILU_C_Object *obj );
/* Publishes the OID of the object in a domain-wide registry */

ILU_PUBLIC ilu_boolean	ILU_C_WithdrawObject ( ILU_C_Object *obj,
					      PASS(char *) proof);
/*
 * Removes the OID of the object from the domain-wide registry.
 * "proof" is the string returned from the publish call.
 */

ILU_PUBLIC OPTIONAL(GLOBAL(ILU_C_Object *))
     ILU_C_LookupObject(RETAIN(char *) sid, RETAIN(char *) ih,
			ilu_Class static_type);
/*
 * Using the local registry, find and return the object specified by
 * the given Server ID and server-relative Instance Handle.
 * "static_type" is one you know the actual object must have; it may
 * also have more refined types.  For an already-reified surrogate
 * this procedure will reconsider what contact info to use for
 * reaching the server.
 */

ILU_PUBLIC OPTIONAL(GLOBAL(ILU_C_Object *))
     ILU_C_ReLookupObject(RETAIN(char *) sid, RETAIN(char *) ih,
			  ilu_Class static_type, int *change);
/*
 * Like ILU_C_LookupObject, but also sets *change to indicate
 * whether a change was made that isn't evident in the result.
 */


/*==== Servers =====================================*/

/*
 * In all of these, the Main Invariant should hold, and L2 is
 * otherwise unrestricted
 */

typedef void    (*ILU_C_WorkProc) (void *arg);
typedef void    (*ILU_C_ForkProc) (ILU_C_WorkProc work, void *arg);

ILU_PUBLIC ilu_boolean ILU_C_SetFork(ILU_C_ForkProc fork);
/*
 * A multi-threaded app or runtime extension calls this, before
 * ILU_C_Run or creating any servers.  Returns true if called in
 * time, false otherwise (this error is not reliably detected; you
 * really ought to get it right).
 */

ILU_PUBLIC void ILU_C_Stoppable_Run(int *stop);

/*
 * A single-threaded app calls this to animate a server or other
 * program.  Invokes the event handling loop.  Never returns.  Allows
 * a value to be passed to the loop.
 */

ILU_PUBLIC void     ILU_C_Run(void);
/*
 * A single-threaded app calls this to animate a server or other
 * program.  Invokes the event handling loop.  Never returns.
 */

ILU_PUBLIC ILU_C_ObjectTable
  ILU_C_CreateObjectTable (
	   /**L1 >= {server};
	      L1 >= {gcmu} if result is true and collectible*/
	   CORBA_Object (*object_of_ih)(ilu_string /* ih */,
					ilu_private /* user_data */),
	   void (*free_ot) (ilu_private /* user_data */),
	   ilu_private user_data);
/* Creates and returns an ObjectTable structure suitable for use with
 * ILU_C_InitializeServer.
 */

/* Main invariant holds */
ILU_PUBLIC          ilu_Server
ILU_C_InitializeServer(OPTIONAL(RETAIN(char *)) serverID,
		       OPTIONAL(GLOBAL(ILU_C_ObjectTable)) obj_tab,
		       OPTIONAL(RETAIN(char *)) protocol,
		       OPTIONAL(RETAIN(ilu_TransportInfo)) transport,
		       ilu_boolean setdefaultport);

/*==================================================*/
/*==================================================*/
/*           For internal use                       */
/*==================================================*/
/*==================================================*/

/* Main invariant holds */
/*
  _ILU_C_GenericCall

  void _ILU_C_GenericCall (ilu_Class class, ilu_Method method,
                           _ILU_C_ExceptionDescription evec,
                           ILU_C_Object *discriminant,
                           ILU_C_ENVIRONMENT *status,
                           char *argdesc, ...)

Operates in varargs mode, off "argdesc".  "argdesc" provides a
description of the arguments to the method, as follows:

"argdesc" contains 2 fields, separated by ':'.

The first field provides a list of the types of all the arguments
which are either In or InOut arguments, each as a one-character code.
The codes are capital letters if the argument is an InOut argument,
lower-case if an In argument.  Specific types are encoded as follows:

  a & A:  short integer
  b & B:  integer
  c & C:  long integer
  d & D:  short cardinal
  e & E:  cardinal
  f & F:  long cardinal
  g & G:  short real
  h & H:  real
  i & I:  long real
  j & J:  short character
  k & K:  character
  l & L:  long character
  m & m:  byte
  n & N:  boolean
  o & O:  enumeration
  p & P:  object
  q & Q:  string
  r & R:  wide string
  z & Z:  other

  s-y & S-Y:  reserved for future use

The following table tells what's found in the varargs list for each case:

a,d,j,k,m,n:	int
b,c,e,f,g,h,i,l,o: <c_parameter_type(t, In)>
A-O:		<c_parameter_type(t, InOut)>
p:		<c_parameter_type(t, In)>,	ilu_Class pclass
P:		<c_parameter_type(t, InOut)>,	ilu_Class pclass
q, r:		<c_parameter_type(t, In)>,	ilu_cardinal limit
Q, R:		<c_parameter_type(t, InOut)>,	ilu_cardinal limit
z:		<c_parameter_type(t, In)>,	ILU_C_{Size,Output}Fn
Z:		<c_parameter_type(t, InOut)>,	ILU_C_{Size,Output}Fn

The sequence of value specified by the first field of "argdesc"
actually appears twice in the varargs part of the _ILU_C_GenericCall
arglist, once for a sizing pass and once for an output pass (there is
no assurance that "va_start" can be called twice in the same
function).

The second field of "argdesc" contains a list of the types of all the
arguments which are either the return type of the method, or Out or
InOut arguments to the method, again as one-character codes, using the
same coding scheme, but this time with lower-case characters
representing Out arguments.  For the purposes of this routine, the
return value of the method is passed and coded as another Out
argument.  The return value argument appears before the actual Out and
InOut arguments in the arglist.

The following table tells what's found in the varargs list for each case:

a-o, A-O:	<c_parameter_type(t, InOut)>
p, P:		<c_parameter_type(t, InOut)>,	ilu_Class pclass
q, r, Q, R:	<c_parameter_type(t, InOut)>,	ilu_cardinal limit
y:		<c_type_role(t, role_InpRet, FALSE)>*, ILU_C_InputFn
z, Z:		<c_parameter_type(t, InOut)>,	ILU_C_InputFn


*/
ILU_PUBLIC void
  _ILU_C_GenericCall (ilu_Class class, ilu_Method method,
		      _ILU_C_ExceptionDescription evec,
		      ILU_C_Object *discriminant,
		      ILU_C_ENVIRONMENT *status,
		      char *argdesc, ...);


/*L1, L2 unconstrained*/
ILU_PUBLIC void
_ILU_C_ConvertError(ILU_C_ENVIRONMENT * env,
		    ilu_Error * err,
		    ILU_C_COMPLETIONSTATUS cstat);
/*
 * Stubs call this when the kernel raises an error, to convert the
 * error into CORBA terms.  Sets *env according to *err and cstat.
 * Calls ILU_HANDLED(*err);
 */

/*L1, L2 unconstrained*/
#define _ILU_C_ConvertErrorQ(env,err,cc) \
	_ILU_C_ConvertError(env,err,ILU_C_COMPLETION(cc))

/*before: not Inside (cobj->server, cobj->type->c) */
/*after:  return != NULL => Inside(cobj->server, cobj->type->c) */
ILU_PUBLIC ilu_Object _ILU_C_KernelObjOfObj(ILU_C_Object *);

/* L1, L2, Main unconstrained */
ILU_PUBLIC void 
_ILU_C_RegisterSurrogateCType(GLOBAL(ilu_Class) ilutype,
			      GLOBAL(ILU_C_Type) ctype);

/* L1, L2, Main unconstrained */
ILU_PUBLIC void    *_ILU_C_FindMethod(RETAIN(ILU_C_Object *),
			          GLOBAL(ilu_Class), int);

/**before: Main Invariant, Call-Hi(call);
    after: Call-Invariant(call, err),
	   success => call->ca_ms == ilu_cmsLo*/
ILU_PUBLIC          ilu_boolean
_ILU_C_FinishParameters(ilu_Call,
			OPTIONAL(ILU_C_Object * disc),
			ILU_ERRS((bad_locks, broken_locks)) *err);
/*
 * Calls ilu_RequestRead, and re-registers request handler if
 * appropriate.
 */

/**before: Main Invariant && Call-Lo(call);
    after: Call-Invariant(call, err),
	   success => call->ca_ms == ilu_cmsHi. */
ILU_PUBLIC ilu_boolean 
_ILU_C_BeginReply(ilu_Call call, ilu_boolean exceptions,
		  ilu_cardinal argSize,
		  ILU_ERRS((bad_locks, IoErrs)) *err);

/**before: Main Invariant && Call-Lo(call);
    after: Call-Invariant(call, err),
	   success => call->ca_ms == ilu_cmsHi. */
ILU_PUBLIC ilu_boolean 
_ILU_C_BeginException(ilu_Call call, ilu_cardinal evalue,
		      ilu_cardinal argSize,
		      ILU_ERRS((bad_locks, IoErrs)) *err);

/**before: Main Invariant, Call-Hi(call);
    after: Call-Invariant(call, err) && Call-Hi(call)*/
ILU_PUBLIC          ilu_boolean
_ILU_C_FinishReply(ilu_Call call, ILU_ERRS((bad_locks, IoErrs)) *err);

/**before: Main Invariant, Call-Hi(call);
    after: Call-Invariant(call, err) && Call-Hi(call)*/
ILU_PUBLIC ilu_boolean 
_ILU_C_FinishException(ilu_Call call, ILU_ERRS((bad_locks, IoErrs)) *err);

/**before: Main Invariant && Call-Lo(call);
    after: Call-Invariant(call, err),
	   success => call->ca_ms == ilu_cmsHi. */
ILU_PUBLIC void 
_ILU_C_SendException(ilu_Call call, _ILU_C_ExceptionDescription evec,
		     ILU_C_ENVIRONMENT * status, ilu_Error * err);

/**before: Main Invariant, Call-Lo(call);
    after: Call-Invariant(call, err),
	   success => call->ca_ms == ilu_cmsNo*/
ILU_PUBLIC          ilu_boolean
_ILU_C_NoReply(ilu_Call call,
	     ILU_ERRS((bad_param, bad_locks, broken_locks)) * err);

/**Before: Call-Invariant(call, err);
    After: Main Invariant*/
ILU_PUBLIC void _ILU_C_FinishServingCall(ilu_Call call, ilu_Error *err);

/* insideServer => Inside(server, class) */
/* otherwise Main invariant holds */
ILU_PUBLIC ILU_C_Object *
_ILU_C_CreateTrueObject(ILU_C_Type type,
			OPTIONAL(ilu_string) instance_handle,
			OPTIONAL(ilu_Server) server,
			void *client_data,
			ilu_boolean inside_server);

/**before: Main Invariant, Call-Hi(call);
    after: Call-Invariant(call, err) && call->ca_ms == ilu_cmsHi*/
ILU_PUBLIC ILU_C_Object *
_ILU_C_GetServerSingleton(ilu_Call, ILU_ERRS((bad_param)) *err);

/*Main invariant, Call-Hi(call)*/
ILU_PUBLIC ILU_C_Object *
_ILU_C_InputObject(ilu_Call call, ilu_Class putative_class,
		   ilu_boolean discriminator_p,
		   ILU_ERRS((IoErrs)) * err);

/*Main invariant, Call-Hi(call)*/
ILU_PUBLIC          ilu_boolean
_ILU_C_OutputObject(ilu_Call call, ILU_C_Object * obj,
		    ilu_Class putative_class,
		    ilu_boolean discriminator_p,
		    ILU_ERRS((IoErrs)) * err);

/* Main invariant holds */
ILU_PUBLIC          ilu_cardinal
_ILU_C_SizeOfObject(ilu_Call call, ILU_C_Object * obj,
		    ilu_Class putative_class,
		    ilu_boolean discriminator_p,
		    ILU_ERRS((IoErrs)) *err);

/* Unrestricted */
ILU_PUBLIC void _ILU_C_ExtendString (CORBA_char **s, CORBA_char item, CORBA_boolean atend);

/* Unrestricted */
ILU_PUBLIC void _ILU_C_ExtendWString (ilu_character **s, ilu_character item, CORBA_boolean atend);

/* Unrestricted */
ILU_PUBLIC void _ILU_C_PopString (CORBA_char **s, CORBA_char *item);

/* Unrestricted */
ILU_PUBLIC void _ILU_C_PopWString (ilu_character **s, ilu_character *item);

/* Unrestricted */
ILU_PUBLIC unsigned int _ILU_C_SafeStrlen(RETAIN(char *str));

/* Unrestricted */
ILU_PUBLIC unsigned int _ILU_C_SafeWStrlen(RETAIN(ilu_character * str));

/* Unrestricted */
ILU_PUBLIC          PASS(void *) _ILU_C_MallocFailure(CORBA_unsigned_long /* nbytes */);

/*Main invariant holds*/
ILU_PUBLIC void     _ILU_C_EnsureGcClient(void);
/* The stubs of an interface that defines collectible object types
   calls this at least once, at intialization time. */

/*======== boolean methods ========================*/
/* Note that CORBA boolean is different from ILU boolean */

ILU_PUBLIC ilu_cardinal ILU_C_SizeOfBoolean (ilu_Call, CORBA_boolean, ilu_Error *);
ILU_PUBLIC void ILU_C_OutputBoolean (ilu_Call, CORBA_boolean, ilu_Error *);
ILU_PUBLIC void ILU_C_InputBoolean (ilu_Call, CORBA_boolean *, ilu_Error *);

/*======== sequence methods ========================*/

/* locking is unconstrained in these */

ILU_PUBLIC void     _ILU_C_AppendGeneric(ILU_C_Sequence h, char *p, int sz);
/* append an element pointed at by `p' of size `sz' to `h' */

ILU_PUBLIC void
_ILU_C_EveryElement(ILU_C_Sequence h,
		    void (*proc) (void *, void *),
		    int sz, void *data);
/* map `proc' over the elements of `h' (each element of size `sz'), calling with (<element>, `data') */

ILU_PUBLIC void     _ILU_C_PopGeneric(ILU_C_Sequence h, char *p, int sz);
/* remove the first element of `h', and return it in buffer pointed at by `p', of size `sz' */

ILU_PUBLIC void     _ILU_C_PushGeneric(ILU_C_Sequence h, char *p, int sz);
/* push the new element pointed at by `p', of size `sz', onto the beginning of `p' */


#undef OPTIONAL
#undef RETAIN
#undef PASS
#undef GLOBAL

#endif

