2 * Copyright (C) 2005-2008, The Perl 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"
50 =item C<static STRING* make_hash_key(PARROT_INTERP, PMC *key)>
52 Returns a Parrot string for C<*key>.
58 static STRING* make_hash_key(PARROT_INTERP, NOTNULL(PMC * key))
61 return VTABLE_get_string(interp, key);
63 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_OUT_OF_BOUNDS,
64 "Hash: Cannot use NULL key");
69 pmclass GDBMHash provides hash dynpmc lib gdbm {
73 =item C<void class_init()>
75 Class initialization. GDBMHash is a dynamic PMC, meaning that a dynamically
76 loadable module is created. On Unix-like systems this is a shared library.
77 When it is available, the shared library has linked in the library 'gdbm'.
79 On WIN32 the relevant library seems to be called 'gdbm3'.
80 So we do a bit of cheating here, and load it during class initialization.
89 /* RT #46393: What if libgdbm.so cannot be loaded */
90 /* Parrot_load_lib(interp, slib, NULL); */
91 STRING *slib = CONST_STRING(interp, "gdbm3");
97 PMC_struct_val(SELF) = NULL;
100 void* get_pointer() {
101 return PMC_struct_val(SELF);
104 void set_pointer(void* p) {
105 PMC_struct_val(SELF) = p;
110 =item C<VOID set_string_native(STRING* value)>
112 Open a or create a new dbm file.
118 void set_string_native(STRING* value) {
119 char *c_db_name = string_to_cstring(interp, value);
120 GDBM_FILE dbf = gdbm_open(c_db_name, 0, GDBM_NEWDB, 0666, 0);
122 string_cstring_free(c_db_name);
124 PMC_struct_val(SELF) = dbf;
129 =item C<INTVAL get_integer()>
131 Returns the number of pairs in the hash.
132 A uninitialized GDBMHash returns 0.
136 RT#46395: This can be optimized by keeping track of number of elements
140 VTABLE INTVAL get_integer() {
141 GDBM_FILE dbf = (GDBM_FILE)PMC_struct_val(SELF);
148 for (key = gdbm_firstkey(dbf); key.dptr; key = nextkey) {
150 nextkey = gdbm_nextkey(dbf, key);
160 =item C<INTVAL get_bool()>
162 Returns true if the hash size is not zero.
168 VTABLE INTVAL get_bool() {
169 GDBM_FILE dbf = (GDBM_FILE)PMC_struct_val(SELF);
174 datum key = gdbm_firstkey(dbf);
186 =item C<void set_string_keyed(PMC *key, STRING *value)>
192 void set_string_keyed(PMC* key, STRING* value) {
194 GDBM_FILE dbf = (GDBM_FILE)PMC_struct_val(SELF);
195 datum key_gdbm, val_gdbm;
199 keystr = make_hash_key(interp, key);
201 key_gdbm.dsize = keystr->strlen;
202 key_gdbm.dptr = keystr->strstart;
203 val_gdbm.dsize = value->strlen;
204 val_gdbm.dptr = value->strstart;
206 gdbm_store(dbf, key_gdbm, val_gdbm, GDBM_REPLACE);
213 =item C<STRING *get_string_keyed(PMC *key)>
215 Returns the string value for the element at C<*key>.
221 STRING* get_string_keyed(PMC* key) {
222 STRING* keystr, *val;
223 GDBM_FILE dbf = (GDBM_FILE)PMC_struct_val(SELF);
224 datum key_gdbm, val_gdbm;
227 return CONST_STRING(INTERP, "");
229 return CONST_STRING(INTERP, "");
230 keystr = make_hash_key(interp, key);
232 key_gdbm.dsize = keystr->strlen;
233 key_gdbm.dptr = keystr->strstart;
234 val_gdbm = gdbm_fetch(dbf, key_gdbm);
236 val = string_from_cstring(interp, val_gdbm.dptr, val_gdbm.dsize);
245 =item C<void set_pmc_keyed(PMC* key, PMC *value)>
247 Convert C<value> to a string and set the string for the C<key>.
253 void set_pmc_keyed(PMC* key, PMC* value) {
256 temp = VTABLE_get_string(interp, value);
257 SELF.set_string_keyed(key, temp);
262 =item C<PMC *get_pmc_keyed(PMC *key)>
264 Returns the PMC value for the element at C<*key>.
270 PMC* get_pmc_keyed(PMC* key) {
271 STRING * ret_string = SELF.get_string_keyed(key);
272 PMC *ret_pmc = pmc_new(interp, enum_class_String);
274 VTABLE_set_string_native(interp, ret_pmc, ret_string);
281 =item C<void set_integer_keyed(PMC* key, INTVAL value)>
283 Convert C<value> to a string and set the string for the C<key>.
289 void set_integer_keyed(PMC* key, INTVAL value) {
292 temp = pmc_new(interp, enum_class_String);
293 VTABLE_set_integer_native(interp, temp, value);
294 SELF.set_pmc_keyed(key, temp);
300 =item C<void set_number_keyed(PMC* key, FLOATVAL value)>
302 Convert C<value> to a string and set the string for the C<key>.
308 void set_number_keyed(PMC* key, FLOATVAL value) {
311 temp = pmc_new(interp, enum_class_String);
312 VTABLE_set_number_native(interp, temp, value);
313 SELF.set_pmc_keyed(key, temp);
318 =item C<INTVAL exists_keyed(PMC *key)>
320 Returns whether a key C<*key> exists in the hash.
326 INTVAL exists_keyed(PMC* key) {
328 GDBM_FILE dbf = (GDBM_FILE)PMC_struct_val(SELF);
333 keystr = make_hash_key(interp, key);
335 key_gdbm.dsize = keystr->strlen;
336 key_gdbm.dptr = keystr->strstart;
338 return gdbm_exists(dbf, key_gdbm);
343 =item C<void delete_keyed(PMC *key)>
345 Deletes the element associated with C<*key>.
351 void delete_keyed(PMC* key) {
353 GDBM_FILE dbf = (GDBM_FILE)PMC_struct_val(SELF);
358 keystr = make_hash_key(interp, key);
360 key_gdbm.dsize = keystr->strlen;
361 key_gdbm.dptr = keystr->strstart;
363 if (gdbm_exists(dbf, key_gdbm)) {
364 gdbm_delete(dbf, key_gdbm);
377 F<docs/pdds/pdd08_keys.pod>, L<http://gdbm.gnu.org>
385 * c-file-style: "parrot"
387 * vim: expandtab shiftwidth=4: