]>
jfr.im git - solanum.git/blob - src/capability.c
2 * Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org>.
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 is present in all copies.
8 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
9 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
12 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
14 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
15 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
16 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
17 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
18 * POSSIBILITY OF SUCH DAMAGE.
22 #include "capability.h"
23 #include "irc_dictionary.h"
25 struct CapabilityIndex
{
26 struct Dictionary
*cap_dict
;
27 unsigned int highest_bit
;
30 #define CAP_ORPHANED 0x1
31 #define CAP_REQUIRED 0x2
33 struct CapabilityEntry
{
40 capability_get(struct CapabilityIndex
*idx
, const char *cap
)
42 struct CapabilityEntry
*entry
;
44 s_assert(idx
!= NULL
);
46 entry
= irc_dictionary_retrieve(idx
->cap_dict
, cap
);
47 if (entry
!= NULL
&& !(entry
->flags
& CAP_ORPHANED
))
48 return (1 << entry
->value
);
54 capability_put(struct CapabilityIndex
*idx
, const char *cap
)
56 struct CapabilityEntry
*entry
;
58 s_assert(idx
!= NULL
);
59 if (!idx
->highest_bit
)
62 if ((entry
= irc_dictionary_retrieve(idx
->cap_dict
, cap
)) != NULL
)
64 entry
->flags
&= ~CAP_ORPHANED
;
65 return (1 << entry
->value
);
68 entry
= rb_malloc(sizeof(struct CapabilityEntry
));
69 entry
->cap
= rb_strdup(cap
);
71 entry
->value
= idx
->highest_bit
;
73 irc_dictionary_add(idx
->cap_dict
, entry
->cap
, entry
);
76 if (idx
->highest_bit
% (sizeof(unsigned int) * 8) == 0)
79 return (1 << entry
->value
);
83 capability_orphan(struct CapabilityIndex
*idx
, const char *cap
)
85 struct CapabilityEntry
*entry
;
87 s_assert(idx
!= NULL
);
89 entry
= irc_dictionary_retrieve(idx
->cap_dict
, cap
);
92 entry
->flags
&= ~CAP_REQUIRED
;
93 entry
->flags
|= CAP_ORPHANED
;
98 capability_require(struct CapabilityIndex
*idx
, const char *cap
)
100 struct CapabilityEntry
*entry
;
102 s_assert(idx
!= NULL
);
104 entry
= irc_dictionary_retrieve(idx
->cap_dict
, cap
);
106 entry
->flags
|= CAP_REQUIRED
;
110 capability_destroy(struct DictionaryElement
*delem
, void *privdata
)
112 s_assert(delem
!= NULL
);
114 rb_free(delem
->data
);
117 struct CapabilityIndex
*
118 capability_index_create(void)
120 struct CapabilityIndex
*idx
;
122 idx
= rb_malloc(sizeof(struct CapabilityIndex
));
123 idx
->cap_dict
= irc_dictionary_create(strcasecmp
);
124 idx
->highest_bit
= 1;
130 capability_index_destroy(struct CapabilityIndex
*idx
)
132 s_assert(idx
!= NULL
);
134 irc_dictionary_destroy(idx
->cap_dict
, capability_destroy
, NULL
);
139 capability_index_list(struct CapabilityIndex
*idx
, unsigned int cap_mask
)
141 struct DictionaryIter iter
;
142 struct CapabilityEntry
*entry
;
143 static char buf
[BUFSIZE
];
147 s_assert(idx
!= NULL
);
151 DICTIONARY_FOREACH(entry
, &iter
, idx
->cap_dict
)
153 if (entry
->value
& cap_mask
)
155 tl
= rb_sprintf(t
, "%s ", entry
->cap
);
167 capability_index_mask(struct CapabilityIndex
*idx
)
169 struct DictionaryIter iter
;
170 struct CapabilityEntry
*entry
;
171 unsigned int mask
= 0;
173 s_assert(idx
!= NULL
);
175 DICTIONARY_FOREACH(entry
, &iter
, idx
->cap_dict
)
177 if (!(entry
->flags
& CAP_ORPHANED
))
178 mask
|= (1 << entry
->value
);
185 capability_index_get_required(struct CapabilityIndex
*idx
)
187 struct DictionaryIter iter
;
188 struct CapabilityEntry
*entry
;
189 unsigned int mask
= 0;
191 s_assert(idx
!= NULL
);
193 DICTIONARY_FOREACH(entry
, &iter
, idx
->cap_dict
)
195 if (!(entry
->flags
& CAP_ORPHANED
) && (entry
->flags
& CAP_REQUIRED
))
196 mask
|= (1 << entry
->value
);