/*
 ******************************************************************************
 *  Copyright 1984-1992 United States Data Corporation. All Rights Reserved.
 ******************************************************************************
 *                                - NOTICE -
 *
 *  The information contained herein is confidential information of United
 *  States Data Corporation, a Delaware corporation, and is protected by
 *  United States copyright and trade secret law and international treaties.
 *  This information is not to be disclosed, used or copied by or transferred
 *  to any individual, corporation, company or other person without the
 *  express written permission of United States Data Corporation.
 ******************************************************************************
 *
 * Module:  FLDTP.H
 *
 *	Header file for tag process API.
 *
 * History:
 *
 *	bjc 10/27/92	Created.
 *	bjc 09/24/93	Version II created.
 *	bjc 05/22/96	Version III created.
 *	knc 06/30/97	Added capability to use HASH table       SPR 6967
 *	knc 08/14/97	Moved prio_ptr[] into DTP structure      SPR 7126
 */


#ifndef _FLDTP_INCLUDED
#define _FLDTP_INCLUDED

#define _USE_TREE_
#ifdef _USE_TREE_
#  ifdef _TREE_INCLUDED
#    define FLDTP_TREE TREE
#  else
#    define FLDTP_TREE void
#  endif
#else
#  define FLDTP_HASH void
#endif /* _USE_TREE_ */

/*
 ************************************************************************
 *                            Constants                                 *
 ************************************************************************
 */

/*
 *  Maximum number of "Fast Acess" entries into the DTP Priority List
 */

#define	MAX_PRI_PTRS	30	/*SPR 6967 "Closest Priority" search*/

/*
 *  Processing control for fldtp_change_read()
 */

#define FLDTP_READ_TOP   0
#define FLDTP_READ_NEXT  1

/*
 *  Processing types for macro fldtp_set_proc_by()
 */

#define FLDTP_BY_FIFO    0
#define FLDTP_BY_PRIO    1

/*
 *  Return codes from FLDTP_CMP_ID functions
 */

#define FLDTP_ID_SAME    0
#define FLDTP_ID_DIFF    1

/*
 *  Determines if tag change bits should be cleared on read
 */

#define FLDTP_READ_CLEAR    0
#define FLDTP_READ_NO_CLEAR 1

/*
 *  Error codes from the FLDTP functions
 */

#define FLDTP_E_GOOD      (0)   /* general sucess indicator */
#define FLDTP_E_INTERNAL  (-1)  /* general error code */
#define FLDTP_E_INVARG    (-2)  /* invalid argument */
#define FLDTP_E_INVTAG    (-3)  /* invalid tag */
#define FLDTP_E_NOMEM     (-4)  /* memory allocation failure */
#define FLDTP_E_NOTFND    (-5)  /* specified tag not found */
#define FLDTP_E_ILLPROC   (-6)  /* illegal func call - FLDTP processing */
#define FLDTP_E_KERFAIL   (-7)  /* kernel access failure */
#define FLDTP_E_UNKTYPE   (-8)  /* unknown tag type */
#define FLDTP_E_NOCHANGE  (-9)  /* no changes to process */


/*
 ************************************************************************
 *                        Structures and Types                          *
 ************************************************************************
 */

/*
 *  Function prototypes for user defined processing
 */

typedef void  (*FLDTP_FUNC_ACTION)(TAG*, VAL*, short, void**);
typedef int   (*FLDTP_FUNC_COMPARE)(void*, void*);
typedef void  (*FLDTP_FUNC_DESTROY)(TAG*, short, void**);

/*
 *  Structure that describes a RTDB element inserted into the FLDTP.  It
 *  is shared between the FLDTP_TAG structure and its children FLDTP_ACTION.
 */
typedef struct
{
	TAG  tag;
	i16  type;

	union
	{
		DIG     dig;
		ANA     ana;
		LANA    lana;
		FLP     flp;
		MSG     *msg;
		MBXMSG  *mbxmsg;
	} v;

} FLDTP_RTDB;

/* Prototypes for forward references */
struct _fldtp_tag;
struct _fldtp;

/*
 *  The FLDTP_ACTION defines a single instance of processing for a tag.
 *  One or more of these structures are chained off the a FLDTP_TAG
 *  structure.
 */
typedef struct _fldtp_action
{
	short  argc;                     /* number of arguments in argv */
	void   **argv;                   /* array of argument pointers */
	void   *id;                      /* CHREC id */
	long   priority;                 /* priority level */
	short  changed;                  /* Tag changed */

	struct _fldtp_tag *dtp_tag;      /* Owning tag for the action */

	FLDTP_FUNC_ACTION  actionf;      /* tag process function */
	FLDTP_FUNC_DESTROY destroyf;     /* destruct handler function */

	struct _fldtp_action *prev_prio; /* previous func in priority list */
	struct _fldtp_action *next_prio; /* next func in priority list */

	struct _fldtp_action *prev;      /* previous func for the tag */
	struct _fldtp_action *next;      /* next func for the tag */

} FLDTP_ACTION;


/*
 *  The FLDTP_TAG defines an instance of a tag to process on change.
 *  The FLDTP_TAG recs are chained off the FLDTP structure.
 */
typedef struct _fldtp_tag
{
	FLDTP_RTDB        rtdb;       /* RTDB info */
	FLDTP_ACTION      *dolist;    /* list of processes linked to tag */
	struct _fldtp     *dtp;       /* owning DTP manager */

	struct _fldtp_tag *prev;      /* previous tag for the FLDTP */
	struct _fldtp_tag *next;      /* next tag for the FLDTP */

} FLDTP_TAG;


/*
 *  The FLDTP is the top-layer structure of the FLDTP.  This structure
 *  contains:
 *
 *	1.  A count of the number of tags loaded into the FLDTP
 *	2.  Linked list of tags to process on change.
 *	3.  Change wait array
 *	4.  Parallel array (to the wait array) of FLDTP_TAG record pointers.
 *	5.  Linked list of process functions sorted by priority
 *	6.  ID comparison function for fldtp_remove()
 *	7.  Status flags
 */
typedef struct _fldtp
{
	long          tagcnt;           /* number of tags in process list */
	FLDTP_TAG     *tags_head;       /* head - list of process tags */
	FLDTP_TAG     *tags_tail;       /* tail - list of process tags */
#ifdef _USE_TREE_
	FLDTP_TREE    *tags_tree;       /* tree contains the above tag list */
#else
	FLDTP_HASH    *tags_hash;       /* SPR 6967 hash contains the above tag list */
#endif /* _USE_TREE_ */

	long          array_slots;      /* number of slots in the arrays */
	long          array_entries;    /* number of tags in the array */
	TAG           *change_array;    /* array of process tags */
	FLDTP_TAG     **chtag_array;    /* array of FLDTP tag struct ptrs */
	u16           msize;            /* size of message read buffer */
	char          *mbuf;            /* message read buffer */

	FLDTP_ACTION  *prio_head;       /* head - prioritized list CHRECs */
	FLDTP_ACTION  *prio_tail;       /* tail - prioritized list CHRECs */

		/* SPR 7126 Moved Fast-Access Index into DTP structure */
	FLDTP_ACTION  *prio_ptr[MAX_PRI_PTRS];	/*SPR 7126 Pri-Locate ptrs */

	FLDTP_FUNC_COMPARE comparef;    /* ID comparison function */

	/*
	 *  These members communicate the state of the FLDTP back to
	 *  the process function.  The state may change due to
	 *  a FLDTP change handler removing and/or deleting items
	 *  from the FLDTP.
	 */

	FLDTP_TAG     *proc_tag;       /* current process tag */
	FLDTP_TAG     *last_read_tag;  /* previous process tag */
	uint          proc_index;      /* index of process tag */
	FLDTP_ACTION  *next_ch4tag;    /* next CHREC on tag do list */
	FLDTP_ACTION  *next_ch4prio;   /* next CHREC on priority list */

	/*
	 *  FLDTP status flags
	 */

	short rtdb_locked;  /* RTDB locked flag */
	short processing;   /* Currently processing flag */
	short proc_by;      /* Process by priority flag */
	short gen_arrays;   /* FLDTP arrays need to be rebuilt */
    short read_clear;   /* FLDTP tag change bits clear flag */

} FLDTP;


/*
 ************************************************************************
 *                              Macros                                  *
 ************************************************************************
 */

#define fldtp_tag_get_tag(dtp_tag)      ((dtp_tag)->rtdb.tag);

/*
 ************************************************************************
 *                         Function Prototypes                          *
 ************************************************************************
 */

#ifdef __cplusplus
extern "C" {
#endif

extern int FLENTRY  fldtp_create(FLDTP **dtp);
extern int FLENTRY  fldtp_destroy(FLDTP *dtp);

extern int FLENTRY  fldtp_insert(FLDTP *dtp, TAG *tag,
                                 FLDTP_FUNC_ACTION afuncp, FLDTP_ACTION **ap);
extern int FLENTRY  fldtp_find_tag(FLDTP *dtp, TAG *tag, FLDTP_TAG **dtp_tag);
extern int FLENTRY  fldtp_remove(FLDTP *dtp, FLDTP_ACTION *del_ap);
extern int FLENTRY  fldtp_remove_group(FLDTP *dtp, TAG *tag,
                                       FLDTP_FUNC_ACTION afuncp, void *id);

extern int FLENTRY  fldtp_change_read(FLDTP *dtp, id_t task_id, int start_from,
                                      FLDTP_TAG **dtp_tag, VAL *val);

extern int FLENTRY  fldtp_proc(FLDTP *dtp, id_t task_id);
extern int FLENTRY  fldtp_proc_action(FLDTP *dtp, FLDTP_ACTION *ap, id_t t_id);
extern int FLENTRY  fldtp_proc_change(FLDTP *dtp, id_t task_id);
extern int FLENTRY  fldtp_proc_tag(FLDTP *dtp, FLDTP_TAG *tag, id_t task_id);
extern int FLENTRY  fldtp_proc_wait(FLDTP *dtp, id_t task_id);

extern int FLENTRY  fldtp_wait(FLDTP *dtp, id_t task_id);

extern int FLENTRY  fldtp_get_tagcnt(FLDTP *dtp, long *tagcnt);
extern int FLENTRY  fldtp_get_msglen(FLDTP *dtp);
extern int FLENTRY  fldtp_set_msglen(FLDTP *dtp, u16 max_mlen);
extern int FLENTRY  fldtp_set_proc_by(FLDTP *dtp, int proc_by);
extern int FLENTRY  fldtp_get_comparef(FLDTP *dtp,
                                       FLDTP_FUNC_COMPARE *comparef);
extern int FLENTRY  fldtp_set_comparef(FLDTP *dtp,
                                       FLDTP_FUNC_COMPARE comparef);

extern int FLENTRY  fldtp_action_get_id(FLDTP_ACTION *ap, void **id);
extern int FLENTRY  fldtp_action_set_id(FLDTP_ACTION *ap, void *id);
extern int FLENTRY  fldtp_action_get_priority(FLDTP_ACTION *ap, long *prio);
extern int FLENTRY  fldtp_action_set_priority(FLDTP_ACTION *ap, long prio);
extern int FLENTRY  fldtp_action_get_args(FLDTP_ACTION *ap, void ***f_argv);
extern int FLENTRY  fldtp_action_set_args(FLDTP_ACTION *ap,
                                          short f_argc, void *f_argv[]);
extern int FLENTRY  fldtp_action_get_destroyf(FLDTP_ACTION *ap,
                                              FLDTP_FUNC_DESTROY *destroyf);
extern int FLENTRY  fldtp_action_set_destroyf(FLDTP_ACTION *ap,
                                              FLDTP_FUNC_DESTROY destroyf);
extern int FLENTRY  fldtp_set_read_no_clear (FLDTP *dtp);
extern int FLENTRY  fldtp_read (FLDTP *dtp, id_t task_id);
extern int FLENTRY  fldtp_set_chng (FLDTP *dtp, id_t task_id);
extern int FLENTRY  fldtp_tag_to_val(FLDTP_TAG *dtp_tag, VAL *val);

#ifdef __cplusplus
}
#endif

#endif

