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