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