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