| 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 | */ |