/*-----------------------------------------------------------------------
   bag.h - utility routines to implement a "bag".

   A bag is a collection of pointers to objects, with no necessary ordering.
   Supported operations:  add, delete, iterate.

   NOTE!  For now (at least), bagAdd() copies the user's data into the
   (fixed-length) slot.

   Copyright (c) 1993-1994 Raima Corporation.  All Rights Reserved.
-----------------------------------------------------------------------*/

/* Offsetof macro definition that doesn't draw warnings from PC-lint.
   WARNING -- the CSet compiler can't handle this.
*/
#if defined(PC_LINT) && defined(offsetof)
#undef offsetof
#define offsetof(s,m)   (size_t)((char *)&(((s *)0)->m) - (char *)0)
#endif

#define BAG_NO_CUR      ((unsigned short)-1)

/* built-in search methods, based on key at specified offset */
#define BAGF_STRCMP     0x0001    /* strcmp */
#define BAGF_STRICMP    0x0002    /* stricmp */
#define BAGF_MEMCMP     0x0003    /* memcmp */
#define BAGF_FIND_MASK  0x007f
#define BAGF_FIND_VIA_PTR   0x0080    /* follow pointer to get to key */

/* flags for control of bag behavior */
#define BAGF_HANDLE     0x0100  /* will be accessed by (short) handle */
#define BAGF_PTR        0x0200  /* bag gets pointer (only) to user's data */
#define BAGF_FIFO       0x0400  /* bag is used for FIFO queue */

typedef struct {
    unsigned short bagc_flag;   /* control info */
    unsigned short bagc_init;   /* initial number of members */
    unsigned short bagc_incr;   /* increment */
    unsigned short bagc_double; /* double allocation if increasing beyond
                                 * this many members
                                 */
    unsigned short bagc_memSize;/* sizeof(member_of_this_bag) */
    short bagc_tag;             /* tag to use for bag's memory allocations */
    size_t bagc_offset;         /* offset to "match pointer" or area */
    unsigned short bagc_nMatch; /* non-zero ==> number of bytes to match */
} BAG_CTRL;

typedef void * BAG_MEM;     /* pointer to member of bag */

typedef struct {
    BAG_CTRL *bag_ctrl;
    unsigned short bag_total;   /* number of elements which are available */
    unsigned short bag_inUse;   /* number of elements which are in use */
    unsigned short bag_cur;     /* index in array of current member */
    unsigned short bag_addPos;  /* position at which to start checking for
                                 * empty slot (to reduce insert time) */
    char *bag_memArray;         /* array of members */
    void *bag_extra;            /* extra info (e.g., map of used slots) */
} BAG;


short REXTERNAL bagCreate(BAG_CTRL *, BAG **);
void REXTERNAL bagDestroy(BAG *);
short REXTERNAL bagAdd(BAG *pBag, void *ptr);
short REXTERNAL bagDelete(BAG *pBag);
short REXTERNAL bagFind(BAG *pBag, void *key, unsigned short *pHandle,
    BAG_MEM *pMem);
short REXTERNAL bagFirst(BAG *pBag);
short REXTERNAL bagGetCurHandle(BAG *pBag, unsigned short *pHandle);
short REXTERNAL bagGetCurPtr(BAG *pBag, BAG_MEM *ppMem);
short REXTERNAL bagGetCurData(BAG *pBag, BAG_MEM pMem);
short REXTERNAL bagLast(BAG *pBag);
short REXTERNAL bagNext(BAG *pBag);
short REXTERNAL bagPrev(BAG *pBag);
short REXTERNAL bagSetCurHandle(BAG *pBag, unsigned short handle);

/*
$Header:   P:/PAT/INCLUDE/VCS/BAG.H_V   1.4   18 Apr 1994 12:09:36   RICHM  $
*/
