1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun Copyright 1995, 1998 The Open Group 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun Permission to use, copy, modify, distribute, and sell this software and its 6*4882a593Smuzhiyun documentation for any purpose is hereby granted without fee, provided that 7*4882a593Smuzhiyun the above copyright notice appear in all copies and that both that 8*4882a593Smuzhiyun copyright notice and this permission notice appear in supporting 9*4882a593Smuzhiyun documentation. 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun The above copyright notice and this permission notice shall be 12*4882a593Smuzhiyun included in all copies or substantial portions of the Software. 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15*4882a593Smuzhiyun EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16*4882a593Smuzhiyun MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17*4882a593Smuzhiyun IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18*4882a593Smuzhiyun OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19*4882a593Smuzhiyun ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20*4882a593Smuzhiyun OTHER DEALINGS IN THE SOFTWARE. 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun Except as contained in this notice, the name of The Open Group shall 23*4882a593Smuzhiyun not be used in advertising or otherwise to promote the sale, use or 24*4882a593Smuzhiyun other dealings in this Software without prior written authorization 25*4882a593Smuzhiyun from The Open Group. 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun */ 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun /* 30*4882a593Smuzhiyun A Set Abstract Data Type (ADT) for the RECORD Extension 31*4882a593Smuzhiyun David P. Wiggins 32*4882a593Smuzhiyun 7/25/95 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun The RECORD extension server code needs to maintain sets of numbers 35*4882a593Smuzhiyun that designate protocol message types. In most cases the interval of 36*4882a593Smuzhiyun numbers starts at 0 and does not exceed 255, but in a few cases (minor 37*4882a593Smuzhiyun opcodes of extension requests) the maximum is 65535. This disparity 38*4882a593Smuzhiyun suggests that a single set representation may not be suitable for all 39*4882a593Smuzhiyun sets, especially given that server memory is precious. We introduce a 40*4882a593Smuzhiyun set ADT to hide implementation differences so that multiple 41*4882a593Smuzhiyun simultaneous set representations can exist. A single interface is 42*4882a593Smuzhiyun presented to the set user regardless of the implementation in use for 43*4882a593Smuzhiyun a particular set. 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun The existing RECORD SI appears to require only four set operations: 46*4882a593Smuzhiyun create (given a list of members), destroy, see if a particular number 47*4882a593Smuzhiyun is a member of the set, and iterate over the members of a set. Though 48*4882a593Smuzhiyun many more set operations are imaginable, to keep the code space down, 49*4882a593Smuzhiyun we won't provide any more operations than are needed. 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun The following types and functions/macros define the ADT. 52*4882a593Smuzhiyun */ 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun /* an interval of set members */ 55*4882a593Smuzhiyun typedef struct { 56*4882a593Smuzhiyun CARD16 first; 57*4882a593Smuzhiyun CARD16 last; 58*4882a593Smuzhiyun } RecordSetInterval; 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun typedef struct _RecordSetRec *RecordSetPtr; /* primary set type */ 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun typedef void *RecordSetIteratePtr; 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun /* table of function pointers for set operations. 65*4882a593Smuzhiyun set users should never declare a variable of this type. 66*4882a593Smuzhiyun */ 67*4882a593Smuzhiyun typedef struct { 68*4882a593Smuzhiyun void (*DestroySet) (RecordSetPtr pSet); 69*4882a593Smuzhiyun unsigned long (*IsMemberOfSet) (RecordSetPtr pSet, int possible_member); 70*4882a593Smuzhiyun RecordSetIteratePtr(*IterateSet) (RecordSetPtr pSet, 71*4882a593Smuzhiyun RecordSetIteratePtr pIter, 72*4882a593Smuzhiyun RecordSetInterval * interval); 73*4882a593Smuzhiyun } RecordSetOperations; 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun /* "base class" for sets. 76*4882a593Smuzhiyun set users should never declare a variable of this type. 77*4882a593Smuzhiyun */ 78*4882a593Smuzhiyun typedef struct _RecordSetRec { 79*4882a593Smuzhiyun RecordSetOperations *ops; 80*4882a593Smuzhiyun } RecordSetRec; 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun RecordSetPtr RecordCreateSet(RecordSetInterval * intervals, 83*4882a593Smuzhiyun int nintervals, void *pMem, int memsize); 84*4882a593Smuzhiyun /* 85*4882a593Smuzhiyun RecordCreateSet creates and returns a new set having members specified 86*4882a593Smuzhiyun by intervals and nintervals. nintervals is the number of RecordSetInterval 87*4882a593Smuzhiyun structures pointed to by intervals. The elements belonging to the new 88*4882a593Smuzhiyun set are determined as follows. For each RecordSetInterval structure, the 89*4882a593Smuzhiyun elements between first and last inclusive are members of the new set. 90*4882a593Smuzhiyun If a RecordSetInterval's first field is greater than its last field, the 91*4882a593Smuzhiyun results are undefined. It is valid to create an empty set (nintervals == 92*4882a593Smuzhiyun 0). If RecordCreateSet returns NULL, the set could not be created due 93*4882a593Smuzhiyun to resource constraints. 94*4882a593Smuzhiyun */ 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun int RecordSetMemoryRequirements(RecordSetInterval * /*pIntervals */ , 97*4882a593Smuzhiyun int /*nintervals */ , 98*4882a593Smuzhiyun int * /*alignment */ 99*4882a593Smuzhiyun ); 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun #define RecordDestroySet(_pSet) \ 102*4882a593Smuzhiyun /* void */ (*_pSet->ops->DestroySet)(/* RecordSetPtr */ _pSet) 103*4882a593Smuzhiyun /* 104*4882a593Smuzhiyun RecordDestroySet frees all resources used by _pSet. _pSet should not be 105*4882a593Smuzhiyun used after it is destroyed. 106*4882a593Smuzhiyun */ 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun #define RecordIsMemberOfSet(_pSet, _m) \ 109*4882a593Smuzhiyun /* unsigned long */ (*_pSet->ops->IsMemberOfSet)(/* RecordSetPtr */ _pSet, \ 110*4882a593Smuzhiyun /* int */ _m) 111*4882a593Smuzhiyun /* 112*4882a593Smuzhiyun RecordIsMemberOfSet returns a non-zero value if _m is a member of 113*4882a593Smuzhiyun _pSet, else it returns zero. 114*4882a593Smuzhiyun */ 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun #define RecordIterateSet(_pSet, _pIter, _interval) \ 117*4882a593Smuzhiyun /* RecordSetIteratePtr */ (*_pSet->ops->IterateSet)(/* RecordSetPtr */ _pSet,\ 118*4882a593Smuzhiyun /* RecordSetIteratePtr */ _pIter, /* RecordSetInterval */ _interval) 119*4882a593Smuzhiyun /* 120*4882a593Smuzhiyun RecordIterateSet returns successive intervals of members of _pSet. If 121*4882a593Smuzhiyun _pIter is NULL, the first interval of set members is copied into _interval. 122*4882a593Smuzhiyun The return value should be passed as _pIter in the next call to 123*4882a593Smuzhiyun RecordIterateSet to obtain the next interval. When the return value is 124*4882a593Smuzhiyun NULL, there were no more intervals in the set, and nothing is copied into 125*4882a593Smuzhiyun the _interval parameter. Intervals appear in increasing numerical order 126*4882a593Smuzhiyun with no overlap between intervals. As such, the list of intervals produced 127*4882a593Smuzhiyun by RecordIterateSet may not match the list of intervals that were passed 128*4882a593Smuzhiyun in RecordCreateSet. Typical usage: 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun pIter = NULL; 131*4882a593Smuzhiyun while (pIter = RecordIterateSet(pSet, pIter, &interval)) 132*4882a593Smuzhiyun { 133*4882a593Smuzhiyun process interval; 134*4882a593Smuzhiyun } 135*4882a593Smuzhiyun */ 136