#include "apricot.h"
#include "guts.h"
#ifdef __cplusplus
extern "C" {
#endif
PHash
prima_hash_create()
{
PHash ret = newHV();
list_add( &prima_guts.static_hashes, ( Handle) ret);
return ret;
}
void
hash_destroy( PHash h, Bool killAll)
{
HE *he;
list_delete( &prima_guts.static_hashes, ( Handle) h);
hv_iterinit( h);
while (( he = hv_iternext( h)) != NULL) {
if ( killAll) free( HeVAL( he));
HeVAL( he) = &PL_sv_undef;
}
sv_free(( SV *) h);
}
static SV *ksv = NULL;
#define ksv_check if ( !ksv) { \
ksv = newSV( keyLen); \
if (!ksv) croak( "GUTS015: Cannot create SV"); \
} \
sv_setpvn( ksv, ( char *) key, keyLen); \
he = hv_fetch_ent( h, ksv, false, 0)
void *
hash_fetch( PHash h, const void *key, int keyLen)
{
HE *he;
ksv_check;
if ( !he) return NULL;
return HeVAL( he);
}
void *
hash_delete( PHash h, const void *key, int keyLen, Bool kill)
{
HE *he;
void *val;
ksv_check;
if ( !he) return NULL;
val = HeVAL( he);
HeVAL( he) = &PL_sv_undef;
(void) hv_delete_ent( h, ksv, G_DISCARD, 0);
if ( kill) {
free( val);
return NULL;
}
return val;
}
Bool
hash_store( PHash h, const void *key, int keyLen, void *val)
{
HE *he;
ksv_check;
if ( he) {
HeVAL( he) = &PL_sv_undef;
(void) hv_delete_ent( h, ksv, G_DISCARD, 0);
}
he = hv_store_ent( h, ksv, &PL_sv_undef, 0);
HeVAL( he) = ( SV *) val;
return true;
}
void *
hash_first_that( PHash h, void * action, void * params, int * pKeyLen, void ** pKey)
{
HE *he;
if ( action == NULL || h == NULL) return NULL;
hv_iterinit(( HV*) h);
for (;;)
{
void *value, *key;
int keyLen;
if (( he = hv_iternext( h)) == NULL)
return NULL;
value = HeVAL( he);
key = HeKEY( he);
keyLen = HeKLEN( he);
if ((( PHashProc) action)( value, keyLen, key, params)) {
if ( pKeyLen) *pKeyLen = keyLen;
if ( pKey) *pKey = key;
return value;
}
}
return NULL;
}
#ifdef __cplusplus
}
#endif