/* 
 * client-structs.h,v 1.1 1994/01/28 17:05:54 franktor Exp
 *
*/
#ifndef CLIENT_STRUCTS_H
#define CLIENT_STRUCTS_H

#ifdef VMS
#include <common-structs.h>
#else
#include <high/common-structs.h>
#endif


/* Open - connect to a server via the high level SR client server */

typedef struct HC_OpenRequest {
   char			*address;
   int			preferredMessageSize;
   int			maximumMessageSize;
   char			*authentification;
   char			*userInformationField;
} HC_OpenRequest;

typedef struct HC_OpenResponse { 
   Boolean		openAccepted;
   char			*message;
   int			preferredMessageSize;
   int			maximumMessageSize;
   Boolean		initialisationStatus;
   char			*implementationId;
   char			*implementationName;
   char			*implementationVersion;
   char			*userInformationField;
} HC_OpenResponse;


/* Search - search in a remote database */

typedef struct HC_SearchRequest {
   int			smallSetUpperBound;
   int			largeSetLowerBound;
   int			mediumSetPresentNumber;
   Boolean		replaceIndicator;
   char			*proposedResultSetId;
   DatabaseName 	*databaseNames;
   RecordComposition 	*smallSetRecordComposition;
   RecordComposition 	*mediumSetRecordComposition;
   char			*preferredRecordSyntax;
   Query		*query;
} HC_SearchRequest;

typedef struct HC_SearchResponse { 
   int			numberOfRecordsFound;
   int			numberOfRecordsReturned;
   int			nextResultSetPosition;
   Boolean		searchStatus;
   ResultSetStatus	resultSetStatus;
   PresentStatus	presentStatus;
   HlvlRecords 		*records;
} HC_SearchResponse;
   

/* Present - present a search result */

typedef struct HC_PresentRequest {
   char			*resultSetId;
   int			resultSetStartPoint;
   int			numberOfRecordsRequested;
   RecordComposition	*recordComposition;
   char			*preferredRecordSyntax;
} HC_PresentRequest;


typedef struct HC_PresentResponse {
   int			numberOfRecordsReturned;
   int			nextResultSetPosition;
   PresentStatus 	presentStatus;
   HlvlRecords		*records;
} HC_PresentResponse;


/* Delete result set */

typedef struct HC_DeleteResultSetRequest { 
   Boolean		all;
   char			*resultSetId;
} HC_DeleteResultSetRequest;

typedef struct HC_DeleteResultSetResponse { 
   Boolean		status;
} HC_DeleteResultSetResponse;


/* Close connection to the high level client server */

typedef struct HC_CloseRequest {
   int			filler;
} HC_CloseRequest;

typedef struct HC_CloseResponse { 
   Boolean		closeAccepted;
   char			*message;
} HC_CloseResponse;  


/*
 * Packet type for transmitting error messages from the client
 * server to the library.  Used when, for instance, a protocol
 * error occurs.
 * If abort is True, the connection to the specified
 * server has been aborted.
 */

typedef struct HC_ErrorMsg {
   char			*message;
   Boolean		abort;
} HC_ErrorMsg;


/*
 * The HS_Packet structure holds the data which is to be sent to the
 * database via the API-2 protocol.
 * I've collected them in a single struct so that the interface will
 * only need one function to send data and one to receive data.
 */

/*
 * enums describing the type (of union) for an highlevel client packet.
 */

typedef enum HC_PacketTypes {
  hcOpenRequest = 0,			hcOpenResponse,
  hcSearchRequest, 			hcSearchResponse,
  hcPresentRequest, 			hcPresentResponse,
  hcDeleteResultSetRequest, 		hcDeleteResultSetResponse,
  hcCloseRequest, 			hcCloseResponse,
  hcErrorMsg,
  hcNone
} HC_PacketTypes;

typedef struct HC_Packet
{
  HC_PacketTypes type;		/* Tells which of the below is used */
  int ref;			/* Identifies which connection for send/receive */
  union
  {				/* the ordering and numbering here must correspond with HC_PacketTypes */
    HC_OpenRequest		*open_request;
    HC_OpenResponse		*open_response;
    HC_SearchRequest		*search_request;
    HC_SearchResponse		*search_response;
    HC_PresentRequest		*present_request;
    HC_PresentResponse		*present_response;
    HC_DeleteResultSetRequest	*delete_result_set_request;
    HC_DeleteResultSetResponse	*delete_result_set_response;
    HC_CloseRequest		*close_request;
    HC_CloseResponse		*close_response;
    HC_ErrorMsg			*error_msg;
  } u;
} HC_Packet;

extern char *HC_Packet_name[];


/*
 * Address and port number of the highlevel client-server
 */

extern char *	hclient_address;
extern int	hclient_port;

/*
 * HC_Initialise():
 * Connects to the high-level client server.
 * Returns True on success, otherwise False.
 */

Boolean HC_Initialise (void);

/*
 * HC_Close():
 * Terminates connection to the high-level client-server.
 * All underlying connections are lost.
 * Returns False if the connection not initialised.
 */

Boolean HC_Close (void);

/*
 * HC_Send():
 * Sends a packet to the high-level client-server.
 * The "ref" variable in struct HC_Packet specifies which connection further
 * from the client-server we want to send the packet through.
 * HC_Send() fills in "ref" when you send an hcOpenRequest, you should
 * use the resulting value in further communication on that connection.
 * Returns True on success, otherwise False, with errno as from HC_Select().
 */

Boolean HC_Send (HC_Packet *pk);

/*
 * HC_Receive():
 * Receives a packet from the high-level client-server, blocking until
 * one arrives.
 * Returns True on success, otherwise False, with errno as from HC_Select().
 */

Boolean HC_Receive (HC_Packet **pk);

/*
 * HC_Select():
 * Waits for activity on specified file descriptors OR until a packet
 * is ready to be fetched by HC_Receive().
 * A positive return value indicates the number of ready descriptors
 * among those supplied.
 * 0 indicates that the time limit has expired.
 * -1 indicates failure, and that errno is set to indicate the error.
 * See manual page for select() for possible errno values.  In addition,
 * these errno values are used to indicate failure to read a packet:
 *	EIO			I/O error
 *	EBADF			Bad file number (ie uninitialised socket)
 *	ECONNABORTED		Software caused connection abort
 * -2 indicates that a packet has arrived from the high-level client-server,
 * and that HC_Receive() now can safely be called to fetch it without
 * risking a block.
 */

int HC_Select (int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
               struct timeval *timeout);

/*
 * HC_FreePacket():
 * Frees a HC_Packet received from/sent to the high-level client-server.
 * If you HC_Free() a packet you have built "by hand", note that all non-NULL
 * pointers in the packet are recursively followed and freed.
 */

void HC_FreePacket (HC_Packet *pk);

/*
 * HC_AllocPacket():
 * Allocate a HC_Packet and its "u" member, and set the type and ref members.
 */

HC_Packet *HC_AllocPacket (HC_PacketTypes type, int ref);

#endif /* CLIENT_STRUCTS_H */
