2 * Copyright (C) 2005-2009, Parrot Foundation.
6 * These are the vtable functions for the GDBMHash PMC
7 * Data Structure and Algorithms:
10 * Please remove unneeded entries.
15 src/dynpmc/gdbmhash.pmc - GDBM PMC
19 This is an interface to the GNU dbm library.
23 On inserted and fetch, keys are converted to STRINGs.
27 PMC insert values are converted to STRINGs.
31 get_integer_keyed() and get_number_keyed() probably don't make any sense,
32 as integers usually can't be converted.
34 When a PMC is requested, a String PMC is returned.
46 #include "parrot/extend.h"
48 typedef struct GDBM_FH {
52 #define PMC_dbfh(x) ((Parrot_GDBMHash_attributes *)PMC_data(x))->db_handle->f
57 =item C<static STRING* make_hash_key(PARROT_INTERP, PMC *key)>
59 Returns a Parrot string for C<*key>.
65 static STRING* make_hash_key(PARROT_INTERP, NOTNULL(PMC * key))
68 return VTABLE_get_string(interp, key);
70 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_OUT_OF_BOUNDS,
71 "Hash: Cannot use NULL key");
76 pmclass GDBMHash provides hash dynpmc lib gdbm {
77 ATTR struct GDBM_FH *db_handle;
81 =item C<void class_init()>
83 Class initialization. GDBMHash is a dynamic PMC, meaning that a dynamically
84 loadable module is created. On Unix-like systems this is a shared library.
85 When it is available, the shared library has linked in the library 'gdbm'.
87 On WIN32 the relevant library seems to be called 'gdbm3'.
88 So we do a bit of cheating here, and load it during class initialization.
94 VTABLE void class_init() {
96 /* TT #1252: What if libgdbm.so cannot be loaded */
97 /* Parrot_load_lib(interp, slib, NULL); */
98 STRING *slib = CONST_STRING(interp, "gdbm3");
103 Parrot_GDBMHash_attributes *attrs =
104 mem_allocate_zeroed_typed(Parrot_GDBMHash_attributes);
106 attrs->db_handle = mem_allocate_zeroed_typed(GDBM_FH);
107 PMC_data(SELF) = attrs;
108 PObj_custom_destroy_SET(SELF);
111 VTABLE void destroy() {
113 ((Parrot_GDBMHash_attributes *)PMC_data(SELF))->db_handle);
114 mem_sys_free(PMC_data(SELF));
115 PMC_data(SELF) = NULL;
118 VTABLE void* get_pointer() {
119 return PMC_dbfh(SELF);
122 VTABLE void set_pointer(void* p) {
123 PMC_dbfh(SELF) = (GDBM_FILE)p;
128 =item C<VOID set_string_native(STRING* value)>
130 Open a or create a new dbm file.
136 VTABLE void set_string_native(STRING* value) {
137 char * const c_db_name = Parrot_str_to_cstring(interp, value);
138 GDBM_FILE dbf = gdbm_open(c_db_name, 0, GDBM_NEWDB, 0666, 0);
140 Parrot_str_free_cstring(c_db_name);
142 PMC_dbfh(SELF) = dbf;
147 =item C<INTVAL get_integer()>
149 Returns the number of pairs in the hash.
150 A uninitialized GDBMHash returns 0.
156 VTABLE INTVAL get_integer() {
157 GDBM_FILE dbf = PMC_dbfh(SELF);
164 for (key = gdbm_firstkey(dbf); key.dptr; key = nextkey) {
166 nextkey = gdbm_nextkey(dbf, key);
176 =item C<INTVAL get_bool()>
178 Returns true if the hash size is not zero.
184 VTABLE INTVAL get_bool() {
185 GDBM_FILE dbf = PMC_dbfh(SELF);
190 datum key = gdbm_firstkey(dbf);
202 =item C<void set_string_keyed(PMC *key, STRING *value)>
208 VTABLE void set_string_keyed(PMC* key, STRING* value) {
210 GDBM_FILE dbf = PMC_dbfh(SELF);
211 datum key_gdbm, val_gdbm;
215 keystr = make_hash_key(interp, key);
217 key_gdbm.dptr = Parrot_str_to_cstring(interp, keystr);
218 key_gdbm.dsize = strlen(key_gdbm.dptr);
219 val_gdbm.dptr = Parrot_str_to_cstring(interp, value);
220 val_gdbm.dsize = strlen(val_gdbm.dptr);
222 gdbm_store(dbf, key_gdbm, val_gdbm, GDBM_REPLACE);
224 Parrot_str_free_cstring(key_gdbm.dptr);
225 Parrot_str_free_cstring(val_gdbm.dptr);
232 =item C<STRING *get_string_keyed(PMC *key)>
234 Returns the string value for the element at C<*key>.
240 VTABLE STRING* get_string_keyed(PMC *key) {
241 STRING *keystr, *val;
242 GDBM_FILE dbf = PMC_dbfh(SELF);
243 datum key_gdbm, val_gdbm;
246 return string_from_literal(INTERP, "");
249 return string_from_literal(INTERP, "");
251 keystr = make_hash_key(interp, key);
253 key_gdbm.dptr = Parrot_str_to_cstring(interp, keystr);
254 key_gdbm.dsize = strlen(key_gdbm.dptr);
255 val_gdbm = gdbm_fetch(dbf, key_gdbm);
257 val = Parrot_str_new(interp, val_gdbm.dptr, val_gdbm.dsize);
258 Parrot_str_free_cstring(key_gdbm.dptr);
267 =item C<void set_pmc_keyed(PMC* key, PMC *value)>
269 Convert C<value> to a string and set the string for the C<key>.
275 VTABLE void set_pmc_keyed(PMC* key, PMC* value) {
278 temp = VTABLE_get_string(interp, value);
279 SELF.set_string_keyed(key, temp);
284 =item C<PMC *get_pmc_keyed(PMC *key)>
286 Returns the PMC value for the element at C<*key>.
292 VTABLE PMC* get_pmc_keyed(PMC* key) {
293 STRING * ret_string = SELF.get_string_keyed(key);
294 PMC *ret_pmc = pmc_new(interp, enum_class_String);
296 VTABLE_set_string_native(interp, ret_pmc, ret_string);
303 =item C<void set_integer_keyed(PMC* key, INTVAL value)>
305 Convert C<value> to a string and set the string for the C<key>.
311 VTABLE void set_integer_keyed(PMC* key, INTVAL value) {
314 temp = pmc_new(interp, enum_class_String);
315 VTABLE_set_integer_native(interp, temp, value);
316 SELF.set_pmc_keyed(key, temp);
322 =item C<void set_number_keyed(PMC* key, FLOATVAL value)>
324 Convert C<value> to a string and set the string for the C<key>.
330 VTABLE void set_number_keyed(PMC* key, FLOATVAL value) {
333 temp = pmc_new(interp, enum_class_String);
334 VTABLE_set_number_native(interp, temp, value);
335 SELF.set_pmc_keyed(key, temp);
340 =item C<INTVAL exists_keyed(PMC *key)>
342 Returns whether a key C<*key> exists in the hash.
348 VTABLE INTVAL exists_keyed(PMC* key) {
350 GDBM_FILE dbf = PMC_dbfh(SELF);
356 keystr = make_hash_key(interp, key);
358 key_gdbm.dptr = Parrot_str_to_cstring(interp, keystr);
359 key_gdbm.dsize = strlen(key_gdbm.dptr);
361 ret = gdbm_exists(dbf, key_gdbm);
362 Parrot_str_free_cstring(key_gdbm.dptr);
369 =item C<void delete_keyed(PMC *key)>
371 Deletes the element associated with C<*key>.
377 VTABLE void delete_keyed(PMC* key) {
379 GDBM_FILE dbf = PMC_dbfh(SELF);
384 keystr = make_hash_key(interp, key);
386 key_gdbm.dptr = Parrot_str_to_cstring(interp, keystr);
387 key_gdbm.dsize = strlen(key_gdbm.dptr);
389 if (gdbm_exists(dbf, key_gdbm)) {
390 gdbm_delete(dbf, key_gdbm);
393 Parrot_str_free_cstring(key_gdbm.dptr);
405 F<docs/pdds/pdd08_keys.pod>, L<http://gdbm.gnu.org>
413 * c-file-style: "parrot"
415 * vim: expandtab shiftwidth=4: