136 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			136 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 | 
						|
Copyright 1995, 1998  The Open Group
 | 
						|
 | 
						|
Permission to use, copy, modify, distribute, and sell this software and its
 | 
						|
documentation for any purpose is hereby granted without fee, provided that
 | 
						|
the above copyright notice appear in all copies and that both that
 | 
						|
copyright notice and this permission notice appear in supporting
 | 
						|
documentation.
 | 
						|
 | 
						|
The above copyright notice and this permission notice shall be
 | 
						|
included in all copies or substantial portions of the Software.
 | 
						|
 | 
						|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
						|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
						|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
						|
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
 | 
						|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 | 
						|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 | 
						|
OTHER DEALINGS IN THE SOFTWARE.
 | 
						|
 | 
						|
Except as contained in this notice, the name of The Open Group shall
 | 
						|
not be used in advertising or otherwise to promote the sale, use or
 | 
						|
other dealings in this Software without prior written authorization
 | 
						|
from The Open Group.
 | 
						|
 | 
						|
*/
 | 
						|
 | 
						|
/*
 | 
						|
	  A Set Abstract Data Type (ADT) for the RECORD Extension
 | 
						|
			   David P. Wiggins
 | 
						|
			       7/25/95
 | 
						|
 | 
						|
    The RECORD extension server code needs to maintain sets of numbers
 | 
						|
    that designate protocol message types.  In most cases the interval of
 | 
						|
    numbers starts at 0 and does not exceed 255, but in a few cases (minor
 | 
						|
    opcodes of extension requests) the maximum is 65535.  This disparity
 | 
						|
    suggests that a single set representation may not be suitable for all
 | 
						|
    sets, especially given that server memory is precious.  We introduce a
 | 
						|
    set ADT to hide implementation differences so that multiple
 | 
						|
    simultaneous set representations can exist.  A single interface is
 | 
						|
    presented to the set user regardless of the implementation in use for
 | 
						|
    a particular set.
 | 
						|
 | 
						|
    The existing RECORD SI appears to require only four set operations:
 | 
						|
    create (given a list of members), destroy, see if a particular number
 | 
						|
    is a member of the set, and iterate over the members of a set.  Though
 | 
						|
    many more set operations are imaginable, to keep the code space down,
 | 
						|
    we won't provide any more operations than are needed.
 | 
						|
 | 
						|
    The following types and functions/macros define the ADT.
 | 
						|
*/
 | 
						|
 | 
						|
/* an interval of set members */
 | 
						|
typedef struct {
 | 
						|
    CARD16 first;
 | 
						|
    CARD16 last;
 | 
						|
} RecordSetInterval;
 | 
						|
 | 
						|
typedef struct _RecordSetRec *RecordSetPtr;     /* primary set type */
 | 
						|
 | 
						|
typedef void *RecordSetIteratePtr;
 | 
						|
 | 
						|
/* table of function pointers for set operations.
 | 
						|
   set users should never declare a variable of this type.
 | 
						|
*/
 | 
						|
typedef struct {
 | 
						|
    void (*DestroySet) (RecordSetPtr pSet);
 | 
						|
    unsigned long (*IsMemberOfSet) (RecordSetPtr pSet, int possible_member);
 | 
						|
     RecordSetIteratePtr(*IterateSet) (RecordSetPtr pSet,
 | 
						|
                                       RecordSetIteratePtr pIter,
 | 
						|
                                       RecordSetInterval * interval);
 | 
						|
} RecordSetOperations;
 | 
						|
 | 
						|
/* "base class" for sets.
 | 
						|
   set users should never declare a variable of this type.
 | 
						|
 */
 | 
						|
typedef struct _RecordSetRec {
 | 
						|
    RecordSetOperations *ops;
 | 
						|
} RecordSetRec;
 | 
						|
 | 
						|
RecordSetPtr RecordCreateSet(RecordSetInterval * intervals,
 | 
						|
                             int nintervals, void *pMem, int memsize);
 | 
						|
/*
 | 
						|
    RecordCreateSet creates and returns a new set having members specified
 | 
						|
    by intervals and nintervals.  nintervals is the number of RecordSetInterval
 | 
						|
    structures pointed to by intervals.  The elements belonging to the new
 | 
						|
    set are determined as follows.  For each RecordSetInterval structure, the
 | 
						|
    elements between first and last inclusive are members of the new set.
 | 
						|
    If a RecordSetInterval's first field is greater than its last field, the
 | 
						|
    results are undefined.  It is valid to create an empty set (nintervals ==
 | 
						|
    0).  If RecordCreateSet returns NULL, the set could not be created due
 | 
						|
    to resource constraints.
 | 
						|
*/
 | 
						|
 | 
						|
int RecordSetMemoryRequirements(RecordSetInterval * /*pIntervals */ ,
 | 
						|
                                int /*nintervals */ ,
 | 
						|
                                int *   /*alignment */
 | 
						|
    );
 | 
						|
 | 
						|
#define RecordDestroySet(_pSet) \
 | 
						|
	/* void */ (*_pSet->ops->DestroySet)(/* RecordSetPtr */ _pSet)
 | 
						|
/*
 | 
						|
    RecordDestroySet frees all resources used by _pSet.  _pSet should not be
 | 
						|
    used after it is destroyed.
 | 
						|
*/
 | 
						|
 | 
						|
#define RecordIsMemberOfSet(_pSet, _m) \
 | 
						|
  /* unsigned long */ (*_pSet->ops->IsMemberOfSet)(/* RecordSetPtr */ _pSet, \
 | 
						|
						   /* int */ _m)
 | 
						|
/*
 | 
						|
    RecordIsMemberOfSet returns a non-zero value if _m is a member of
 | 
						|
    _pSet, else it returns zero.
 | 
						|
*/
 | 
						|
 | 
						|
#define RecordIterateSet(_pSet, _pIter, _interval) \
 | 
						|
 /* RecordSetIteratePtr */ (*_pSet->ops->IterateSet)(/* RecordSetPtr */ _pSet,\
 | 
						|
	/* RecordSetIteratePtr */ _pIter, /* RecordSetInterval */ _interval)
 | 
						|
/*
 | 
						|
    RecordIterateSet returns successive intervals of members of _pSet.  If
 | 
						|
    _pIter is NULL, the first interval of set members is copied into _interval.
 | 
						|
    The return value should be passed as _pIter in the next call to
 | 
						|
    RecordIterateSet to obtain the next interval.  When the return value is
 | 
						|
    NULL, there were no more intervals in the set, and nothing is copied into
 | 
						|
    the _interval parameter.  Intervals appear in increasing numerical order
 | 
						|
    with no overlap between intervals.  As such, the list of intervals produced
 | 
						|
    by RecordIterateSet may not match the list of intervals that were passed
 | 
						|
    in RecordCreateSet.  Typical usage:
 | 
						|
 | 
						|
	pIter = NULL;
 | 
						|
	while (pIter = RecordIterateSet(pSet, pIter, &interval))
 | 
						|
	{
 | 
						|
	    process interval;
 | 
						|
	}
 | 
						|
*/
 |