xref: /OK3568_Linux_fs/external/xserver/record/set.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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