Initial import.
[mLib-python] / sym.pyx
CommitLineData
20bce5e9 1# -*-pyrex-*-
2#
3# $Id$
4#
5# Symbol table, using universal hashing
6#
7# (c) 2005 Straylight/Edgeware
8#
9
10#----- Licensing notice -----------------------------------------------------
11#
12# This file is part of the Python interface to mLib.
13#
14# mLib/Python is free software; you can redistribute it and/or modify
15# it under the terms of the GNU General Public License as published by
16# the Free Software Foundation; either version 2 of the License, or
17# (at your option) any later version.
18#
19# mLib/Python is distributed in the hope that it will be useful,
20# but WITHOUT ANY WARRANTY; without even the implied warranty of
21# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22# GNU General Public License for more details.
23#
24# You should have received a copy of the GNU General Public License
25# along with mLib/Python; if not, write to the Free Software Foundation,
26# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27
28cdef extern from 'mLib/sym.h':
29 ctypedef struct sym_table:
30 pass
31 ctypedef struct sym_base:
32 pass
33 ctypedef struct sym_iter:
34 pass
35 void sym_create(sym_table *t)
36 void sym_destroy(sym_table *t)
37 void *sym_find(sym_table *t, char *n, long l, int sz, unsigned *f)
38 void sym_remove(sym_table *t, void *b)
39 char *SYM_NAME(void *b)
40 int SYM_LEN(void *b)
41 void sym_mkiter(sym_iter *i, sym_table *t)
42 void *sym_next(sym_iter *i)
43
44cdef extern from 'grim.h':
45 int PSIZEOF(void *p)
46
47cdef extern from 'Python.h':
48 int PyObject_AsReadBuffer(obj, void **buf, int *len) except -1
49 PyString_FromStringAndSize(char *p, int n)
50 ctypedef struct PyObject:
51 pass
52 void Py_INCREF(PyObject *obj)
53 void Py_DECREF(PyObject *obj)
54
55cdef struct entry:
56 sym_base _b
57 PyObject *v
58
59cdef entry *_find(sym_table *t, object k, unsigned *f) except ?NULL:
60 cdef void *p
61 cdef int n
62 cdef entry *e
63 PyObject_AsReadBuffer(key, &p, &n)
64 if f:
65 f[0] = 0
66 e = <entry *>sym_find(t, <char *>p, n, PSIZEOF(e), f)
67 if not f[0]:
68 e.v = NULL
69 else:
70 e = <entry *>sym_find(t, <char *>p, n, 0, NULL)
71 return e
72
73cdef _eget(entry *e):
74 Py_INCREF(e.v)
75 return <object>e.v
76
77cdef void _eset(entry *e, v):
78 if e.v:
79 Py_DECREF(e.v)
80 e.v = <PyObject *>v
81 Py_INCREF(e.v)
82
83cdef void _edel(sym_table *t, entry *e):
84 if e.v:
85 Py_DECREF(e.v)
86 sym_remove(t, <void *>e)
87
88cdef _key(entry *e):
89 return PyString_FromStringAndSize(SYM_NAME(<void *>e), SYM_LEN(<void *>e))
90
91cdef class Table:
92 cdef sym_table _t
93 def __new__(me, *hunoz, **hukairz):
94 sym_create(&me._t)
95 def __init__(me, stuff = None, **kw):
96 me.update(stuff, kw)
97 def __getitem__(me, key):
98 cdef entry *e
99 e = _find(&me._t, key, NULL)
100 if not e:
101 raise KeyError, key
102 return _eget(e)
103 def __setitem__(me, key, value):
104 cdef unsigned f
105 _eset(_find(&me._t, key, &f), value)
106 def __delitem__(me, key):
107 cdef entry *e
108 cdef unsigned f
109 e = _find(&me._t, key, &f)
110 if not e:
111 raise KeyError, key
112 _edel(&me._t, e)
113 def get(me, key, default = None):
114 cdef entry *e
115 e = _find(&me._t, key, NULL)
116 if not e:
117 return default
118 return _eget(e)
119 def setdefault(me, key, default = None):
120 cdef entry *e
121 cdef unsigned f
122 e = _find(&me._t, key, &f)
123 if f:
124 return _eget(e)
125 else:
126 _eset(e, default)
127 return default
128 def pop(me, key, default = None):
129 cdef entry *e
130 e = _find(&me._t, key, NULL)
131 if not e:
132 return default
133 rc = _eget(e)
134 _edel(&me._t, e)
135 return rc
136 def popitem(me):
137 cdef entry *e
138 cdef sym_iter i
139 sym_mkiter(&i, &me._t)
140 e = <entry *>sym_next(&i)
141 if not e:
142 raise ValueError, 'popitem(): table is empty'
143 return _key(e), _eget(e)
144 def keys(me):
145 cdef sym_iter i
146 cdef entry *e
147 l = []
148 sym_mkiter(&i, &me._t)
149 while 1:
150 e = <entry *>sym_next(&i)
151 if not e:
152 break
153 l.append(_key(e))
154 return l
155 def values(me):
156 cdef sym_iter i
157 cdef entry *e
158 l = []
159 sym_mkiter(&i, &me._t)
160 while 1:
161 e = <entry *>sym_next(&i)
162 if not e:
163 break
164 l.append(_eget(e))
165 return l
166 def items(me):
167 cdef sym_iter i
168 cdef entry *e
169 l = []
170 sym_mkiter(&i, &me._t)
171 while 1:
172 e = <entry *>sym_next(&i)
173 if not e:
174 break
175 l.append((_key(e), _eget(e)))
176 return l
177 def clear(me):
178 cdef sym_iter i
179 cdef entry *e
180 sym_mkiter(&i, &me._t)
181 while 1:
182 e = <entry *>sym_next(&i)
183 if not e:
184 break
185 _edel(&me._t, e)
186 return me
187 def __dealloc__(me):
188 cdef sym_iter i
189 cdef entry *e
190 sym_mkiter(&i, &me._t)
191 while 1:
192 e = <entry *>sym_next(&i)
193 if not e:
194 break
195 _edel(&me._t, e)
196 sym_destroy(&me._t)
197 def iterkeys(me):
198 return KeyIter(me)
199 def __iter__(me):
200 return KeyIter(me)
201 def itervalues(me):
202 return ValueIter(me)
203 def iteritems(me):
204 return ItemIter(me)
205 def update(me, stuff = None, **kw):
206 cdef unsigned f
207 if stuff is None:
208 pass
209 elif hasattr(stuff, 'itemiter'):
210 for k, v in stuff.itemiter:
211 _eset(_find(&me._t, k, &f), v)
212 elif hasattr(stuff, 'keys'):
213 for k in stuff.keys():
214 _eset(_find(&me._t, k, &f), stuff[k])
215 else:
216 for k, v in stuff:
217 _eset(_find(&me._t, k, &f), v)
218 for k, v in kw.iteritems():
219 _eset(_find(&me._t, k, &f), v)
220 return me
221
222cdef class KeyIter:
223 cdef Table _t
224 cdef sym_iter _i
225 def __new__(me, Table t):
226 me._t = t
227 sym_mkiter(&me._i, &t._t)
228 def __iter__(me):
229 return me
230 def __next__(me):
231 cdef entry *e
232 e = <entry *>sym_next(&me._i)
233 if not e:
234 raise StopIteration
235 return _key(e)
236
237cdef class ValueIter:
238 cdef Table _t
239 cdef sym_iter _i
240 def __new__(me, Table t):
241 me._t = t
242 sym_mkiter(&me._i, &t._t)
243 def __iter__(me):
244 return me
245 def __next__(me):
246 cdef entry *e
247 e = <entry *>sym_next(&me._i)
248 if not e:
249 raise StopIteration
250 return _eget(e)
251
252cdef class ItemIter:
253 cdef Table _t
254 cdef sym_iter _i
255 def __new__(me, Table t):
256 me._t = t
257 sym_mkiter(&me._i, &t._t)
258 def __iter__(me):
259 return me
260 def __next__(me):
261 cdef entry *e
262 e = <entry *>sym_next(&me._i)
263 if not e:
264 raise StopIteration
265 return _key(e), _eget(e)
266
267#----- That's all, folks ----------------------------------------------------