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