annotate mcabber/libjabber/hashtable.c @ 430:d03663d2e7d9

Display error messages as specified in RFC3920 (9.3) If possible, we display the child element corresponding to the stanza error conditions defined in RFC3920. Error code and error text will be displayed if available.
author Mikael Berthe <mikael@lilotux.net>
date Sun, 11 Sep 2005 22:01:57 +0200
parents bf3d6e241714
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
25
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
1 /*
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
2 The contents of this file are subject to the Mozilla Public License
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
3 Version 1.1 (the "License"); you may not use this file except in
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
4 csompliance with the License. You may obtain a copy of the License at
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
5 http://www.mozilla.org/MPL/
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
6
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
7 Software distributed under the License is distributed on an "AS IS"
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
8 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
9 License for the specific language governing rights and limitations
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
10 under the License.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
11
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
12 The Original Code is expat.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
13
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
14 The Initial Developer of the Original Code is James Clark.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
15 Portions created by James Clark are Copyright (C) 1998, 1999
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
16 James Clark. All Rights Reserved.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
17
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
18 Contributor(s):
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
19
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
20 Alternatively, the contents of this file may be used under the terms
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
21 of the GNU General Public License (the "GPL"), in which case the
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
22 provisions of the GPL are applicable instead of those above. If you
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
23 wish to allow use of your version of this file only under the terms of
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
24 the GPL and not to allow others to use your version of this file under
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
25 the MPL, indicate your decision by deleting the provisions above and
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
26 replace them with the notice and other provisions required by the
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
27 GPL. If you do not delete the provisions above, a recipient may use
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
28 your version of this file under either the MPL or the GPL.
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
29 */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
30
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
31 #include "xmldef.h"
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
32
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
33 #ifdef XML_UNICODE_WCHAR_T
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
34 #ifndef XML_UNICODE
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
35 #define XML_UNICODE
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
36 #endif
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
37 #endif
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
38
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
39 #include "hashtable.h"
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
40
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
41 #define INIT_SIZE 64
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
42
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
43 static
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
44 int keyeq(KEY s1, KEY s2)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
45 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
46 for (; *s1 == *s2; s1++, s2++)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
47 if (*s1 == 0)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
48 return 1;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
49 return 0;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
50 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
51
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
52 static
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
53 unsigned long hash(KEY s)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
54 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
55 unsigned long h = 0;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
56 while (*s)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
57 h = (h << 5) + h + (unsigned char)*s++;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
58 return h;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
59 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
60
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
61 NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
62 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
63 size_t i;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
64 if (table->size == 0) {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
65 if (!createSize)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
66 return 0;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
67 table->v = calloc(INIT_SIZE, sizeof(NAMED *));
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
68 if (!table->v)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
69 return 0;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
70 table->size = INIT_SIZE;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
71 table->usedLim = INIT_SIZE / 2;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
72 i = hash(name) & (table->size - 1);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
73 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
74 else {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
75 unsigned long h = hash(name);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
76 for (i = h & (table->size - 1);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
77 table->v[i];
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
78 i == 0 ? i = table->size - 1 : --i) {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
79 if (keyeq(name, table->v[i]->name))
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
80 return table->v[i];
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
81 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
82 if (!createSize)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
83 return 0;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
84 if (table->used == table->usedLim) {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
85 /* check for overflow */
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
86 size_t newSize = table->size * 2;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
87 NAMED **newV = calloc(newSize, sizeof(NAMED *));
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
88 if (!newV)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
89 return 0;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
90 for (i = 0; i < table->size; i++)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
91 if (table->v[i]) {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
92 size_t j;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
93 for (j = hash(table->v[i]->name) & (newSize - 1);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
94 newV[j];
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
95 j == 0 ? j = newSize - 1 : --j)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
96 ;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
97 newV[j] = table->v[i];
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
98 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
99 free(table->v);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
100 table->v = newV;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
101 table->size = newSize;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
102 table->usedLim = newSize/2;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
103 for (i = h & (table->size - 1);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
104 table->v[i];
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
105 i == 0 ? i = table->size - 1 : --i)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
106 ;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
107 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
108 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
109 table->v[i] = calloc(1, createSize);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
110 if (!table->v[i])
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
111 return 0;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
112 table->v[i]->name = name;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
113 (table->used)++;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
114 return table->v[i];
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
115 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
116
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
117 void hashTableDestroy(HASH_TABLE *table)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
118 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
119 size_t i;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
120 for (i = 0; i < table->size; i++) {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
121 NAMED *p = table->v[i];
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
122 if (p)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
123 free(p);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
124 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
125 free(table->v);
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
126 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
127
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
128 void hashTableInit(HASH_TABLE *p)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
129 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
130 p->size = 0;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
131 p->usedLim = 0;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
132 p->used = 0;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
133 p->v = 0;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
134 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
135
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
136 void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
137 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
138 iter->p = table->v;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
139 iter->end = iter->p + table->size;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
140 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
141
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
142 NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
143 {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
144 while (iter->p != iter->end) {
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
145 NAMED *tem = *(iter->p)++;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
146 if (tem)
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
147 return tem;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
148 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
149 return 0;
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
150 }
bf3d6e241714 [/trunk] Changeset 41 by mikael
mikael
parents:
diff changeset
151