The attached patch adds three functions for dereferencing an APR hash
index (iterator). The usage of apr_hash_this() can look something like:

  for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
    {
      const char *name;
      svn_wc_entry_t *wc_entry;
      const void *key;
      void *val;

      apr_hash_this(hi, &key, NULL, &val);
      name = key;
      wc_entry = val;

      ... (code that uses the key "name" and value "wc_entry") ...
    }

The reason for the temporary variables "key" and "val" is that you can't
pass pointers to the correct-type variables ("name" and "wc_entry") to
apr_hash_this() without getting pointer type warnings on typical
compilers.

With the attached patch, the above can be rewritten as:

  for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
    {
      const char *item = apr_hash_index_key(hi);
      svn_wc_entry_t *entry = apr_hash_index_val(hi);

      ... (code that uses the key "name" and value "wc_entry") ...
    }

We have just started using these functions (but with an additional
"svn_" prefix) in Subversion today, because the source code can then be
much cleaner.

I offer and recommend this patch for inclusion in APR. Please let me
know whether this is suitable or if there is anything I should do to
help get it in.

Thanks.
- Julian

Add functions to dereference an APR hash table index. The caller can get the
values into variables of the correct types much more succinctly than by using
apr_hash_this(), and without using type casts or temporary variables.

* include/apr_hash.h,
  tables/apr_hash.c
  (apr_hash_index_key, apr_hash_index_klen, apr_hash_index_val):
    New functions.
--This line, and those below, will be ignored--

Index: include/apr_hash.h
===================================================================
--- include/apr_hash.h	(revision 792588)
+++ include/apr_hash.h	(working copy)
@@ -168,6 +168,27 @@ APR_DECLARE(void) apr_hash_this(apr_hash
                                 apr_ssize_t *klen, void **val);
 
 /**
+ * Get the current entry's key from the iteration state.
+ * @param hi The iteration state
+ * @return The pointer to the key.
+ */
+APR_DECLARE(const void *) apr_hash_index_key(apr_hash_index_t *hi);
+
+/**
+ * Get the current entry's key from the iteration state.
+ * @param hi The iteration state
+ * @return The key length.
+ */
+APR_DECLARE(apr_ssize_t) apr_hash_index_klen(apr_hash_index_t *hi);
+
+/**
+ * Get the current entry's key from the iteration state.
+ * @param hi The iteration state
+ * @return The associated value.
+ */
+APR_DECLARE(void *) apr_hash_index_val(apr_hash_index_t *hi);
+
+/**
  * Get the number of key/value pairs in the hash table.
  * @param ht The hash table
  * @return The number of key/value pairs in the hash table.
Index: tables/apr_hash.c
===================================================================
--- tables/apr_hash.c	(revision 792588)
+++ tables/apr_hash.c	(working copy)
@@ -156,6 +156,21 @@ APR_DECLARE(void) apr_hash_this(apr_hash
     if (val)  *val  = (void *)hi->this->val;
 }
 
+APR_DECLARE(const void *) apr_hash_index_key(apr_hash_index_t *hi)
+{
+    return hi->this->key;
+}
+
+APR_DECLARE(apr_ssize_t) apr_hash_index_klen(apr_hash_index_t *hi)
+{
+    return hi->this->klen;
+}
+
+APR_DECLARE(void *) apr_hash_index_val(apr_hash_index_t *hi)
+{
+    return (void *)hi->this->val;
+}
+
 
 /*
  * Expanding a hash table

Reply via email to