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