#include "perl_xmmsclient.h" #define xmmsc_result_propdict_t xmmsc_result_t void perl_xmmsclient_extract_keys_from_propdict (const void *key, xmmsc_result_value_type_t type, const void *value, const char *source, void *user_data) { HV *keys = (HV *)user_data; hv_store (keys, key, strlen (key), &PL_sv_undef, 0); } HV * perl_xmmsclient_get_keys_if_needed (SV *sv) { HV *keys; SV **hash_elem; int ret = 0; MAGIC *mg = NULL; xmmsc_result_propdict_t *res = NULL; hash_elem = hv_fetch ((HV *)SvRV (sv), "keys", 4, 0); if (hash_elem == NULL || *hash_elem == NULL) { if (!(mg = perl_xmmsclient_get_magic_from_sv (sv, "Audio::XMMSClient::Result::PropDict::Tie"))) { croak ("This is a bug!"); } res = (xmmsc_result_propdict_t *)mg->mg_ptr; keys = newHV (); ret = xmmsc_result_propdict_foreach (res, perl_xmmsclient_extract_keys_from_propdict, keys); hash_elem = hv_store ((HV *)SvRV (sv), "keys", 4, newRV_noinc ((SV *)keys), 0); } keys = (HV *)SvRV (*hash_elem); return keys; } MODULE = Audio::XMMSClient::Result::PropDict::Tie PACKAGE = Audio::XMMSClient::Result::PropDict::Tie SV * FIRSTKEY (sv) SV *sv PREINIT: HV *keys; HE *iter; char *key; I32 key_len; CODE: keys = perl_xmmsclient_get_keys_if_needed (sv); hv_iterinit (keys); iter = hv_iternext (keys); key = hv_iterkey (iter, &key_len); RETVAL = newSVpv (key, key_len); OUTPUT: RETVAL SV * NEXTKEY (sv, lastkey) SV *sv PREINIT: HV *keys; HE *iter; char *key; I32 key_len; CODE: keys = perl_xmmsclient_get_keys_if_needed (sv); iter = hv_iternext (keys); if (iter == NULL) { RETVAL = &PL_sv_undef; } else { key = hv_iterkey (iter, &key_len); RETVAL = newSVpv (key, key_len); } OUTPUT: RETVAL SV * FETCH (res, key) xmmsc_result_propdict_t *res char *key PREINIT: int ret = 0; uint32_t uint32_val; int32_t int32_val; char *string_val; CODE: switch (xmmsc_result_get_dict_entry_type (res, key)) { case XMMS_OBJECT_CMD_ARG_UINT32: ret = xmmsc_result_get_dict_entry_uint (res, key, &uint32_val); RETVAL = newSVuv (uint32_val); break; case XMMS_OBJECT_CMD_ARG_INT32: ret = xmmsc_result_get_dict_entry_int (res, key, &int32_val); RETVAL = newSViv (int32_val); break; case XMMS_OBJECT_CMD_ARG_STRING: ret = xmmsc_result_get_dict_entry_string (res, key, &string_val); RETVAL = newSVpv (string_val, 0); break; default: RETVAL = &PL_sv_undef; } if (ret != 1) { RETVAL = &PL_sv_undef; } OUTPUT: RETVAL BOOT: PERL_UNUSED_VAR (items);