Detect FPU by checking CPUID features.
[dragonfly.git] / contrib / bind-9.5.2 / lib / isc / portset.c
1 /*
2  * Copyright (C) 2008  Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /* $Id: portset.c,v 1.2.2.3 2008/06/24 23:26:49 marka Exp $ */
18
19 /*! \file */
20
21 #include <config.h>
22
23 #include <isc/mem.h>
24 #include <isc/portset.h>
25 #include <isc/string.h>
26 #include <isc/types.h>
27 #include <isc/util.h>
28
29 #define ISC_PORTSET_BUFSIZE (65536 / (sizeof(isc_uint32_t) * 8))
30
31 /*%
32  * Internal representation of portset.  It's an array of 32-bit integers, each
33  * bit corresponding to a single port in the ascending order.  For example,
34  * the second most significant bit of buf[0] corresponds to port 1.
35  */
36 struct isc_portset {
37         unsigned int nports;    /*%< number of ports in the set */
38         isc_uint32_t buf[ISC_PORTSET_BUFSIZE];
39 };
40
41 static inline isc_boolean_t
42 portset_isset(isc_portset_t *portset, in_port_t port) {
43         return (ISC_TF((portset->buf[port >> 5] & (1 << (port & 31))) != 0));
44 }
45
46 static inline void
47 portset_add(isc_portset_t *portset, in_port_t port) {
48         if (!portset_isset(portset, port)) {
49                 portset->nports++;
50                 portset->buf[port >> 5] |= (1 << (port & 31));
51         }
52 }
53
54 static inline void
55 portset_remove(isc_portset_t *portset, in_port_t port) {
56         if (portset_isset(portset, port)) {
57                 portset->nports--;
58                 portset->buf[port >> 5] &= ~(1 << (port & 31));
59         }
60 }
61
62 isc_result_t
63 isc_portset_create(isc_mem_t *mctx, isc_portset_t **portsetp) {
64         isc_portset_t *portset;
65
66         REQUIRE(portsetp != NULL && *portsetp == NULL);
67
68         portset = isc_mem_get(mctx, sizeof(*portset));
69         if (portset == NULL)
70                 return (ISC_R_NOMEMORY);
71
72         /* Make the set 'empty' by default */
73         memset(portset, 0, sizeof(*portset));
74         *portsetp = portset;
75
76         return (ISC_R_SUCCESS);
77 }
78
79 void
80 isc_portset_destroy(isc_mem_t *mctx, isc_portset_t **portsetp) {
81         isc_portset_t *portset;
82
83         REQUIRE(portsetp != NULL);
84         portset = *portsetp;
85
86         isc_mem_put(mctx, portset, sizeof(*portset));
87 }
88
89 isc_boolean_t
90 isc_portset_isset(isc_portset_t *portset, in_port_t port) {
91         REQUIRE(portset != NULL);
92
93         return (portset_isset(portset, port));
94 }
95
96 unsigned int
97 isc_portset_nports(isc_portset_t *portset) {
98         REQUIRE(portset != NULL);
99
100         return (portset->nports);
101 }
102
103 void
104 isc_portset_add(isc_portset_t *portset, in_port_t port) {
105         REQUIRE(portset != NULL);
106
107         portset_add(portset, port);
108 }
109
110 void
111 isc_portset_remove(isc_portset_t *portset, in_port_t port) {
112         portset_remove(portset, port);
113 }
114
115 void
116 isc_portset_addrange(isc_portset_t *portset, in_port_t port_lo,
117                      in_port_t port_hi)
118 {
119         in_port_t p;
120
121         REQUIRE(portset != NULL);
122         REQUIRE(port_lo <= port_hi);
123
124         p = port_lo;
125         do {
126                 portset_add(portset, p);
127         } while (p++ < port_hi);
128 }
129
130 void
131 isc_portset_removerange(isc_portset_t *portset, in_port_t port_lo,
132                         in_port_t port_hi)
133 {
134         in_port_t p;
135
136         REQUIRE(portset != NULL);
137         REQUIRE(port_lo <= port_hi);
138
139         p = port_lo;
140         do {
141                 portset_remove(portset, p);
142         } while (p++ < port_hi);
143 }