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