? Perhaps
? config.nice
Index: docs/api/APR/Table.pod
===================================================================
RCS file: /home/cvspublic/modperl-docs/src/docs/2.0/api/APR/Table.pod,v
retrieving revision 1.9
diff -u -r1.9 Table.pod
--- docs/api/APR/Table.pod	22 May 2004 02:03:26 -0000	1.9
+++ docs/api/APR/Table.pod	13 Jul 2004 06:20:56 -0000
@@ -955,7 +955,20 @@
 
 =back
 
+When iterating through the table's entries
+with each, FETCH will return the current value
+of a multivalued key.  For example
 
+  $table->add("a" => 1);
+  $table->add("b" => 2);
+  $table->add("c" => 3);
+
+  ($k, $v) = each %$table; # (a, 1)      
+  print $t->{a};           # prints 1
+
+  ($k, $v) = each %$table; # (b, 3)      
+  ($k, $v) = each %$table; # (a, 3)      
+  print $t->{a};           # prints 3
 
 
 =head1 See Also
Index: src/modules/perl/modperl_common_util.c
===================================================================
RCS file: /home/cvspublic/modperl-2.0/src/modules/perl/modperl_common_util.c,v
retrieving revision 1.2
diff -u -r1.2 modperl_common_util.c
--- src/modules/perl/modperl_common_util.c	22 Jun 2004 22:34:10 -0000	1.2
+++ src/modules/perl/modperl_common_util.c	13 Jul 2004 06:20:57 -0000
@@ -22,6 +22,20 @@
 
 #include "modperl_common_util.h"
 
+static int modperl_table_magic_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv, 
+                                    const char *name, int namelen)
+{
+    /* prefetch the value whenever we're iterating over the keys */
+    MAGIC *tie_magic = mg_find(nsv, PERL_MAGIC_tiedelem);
+    SV *obj = SvRV(tie_magic->mg_obj);
+    if (SvCUR(obj))
+        SvGETMAGIC(nsv);
+    return 0;
+}
+
+static const MGVTBL modperl_table_magic_prefetch = {0, 0, 0, 0, 0, 
+                                                    modperl_table_magic_copy};
+
 MP_INLINE SV *modperl_hash_tie(pTHX_ 
                                const char *classname,
                                SV *tsv, void *p)
@@ -30,15 +44,19 @@
     SV *rsv = sv_newmortal();
 
     sv_setref_pv(rsv, classname, p);
+
+    sv_magic(hv, NULL, PERL_MAGIC_ext, Nullch, -1);
+    SvMAGIC(hv)->mg_virtual = (MGVTBL *)&modperl_table_magic_prefetch;
+    SvMAGIC(hv)->mg_flags |= MGf_COPY;
     sv_magic(hv, rsv, PERL_MAGIC_tied, Nullch, 0);
 
     return SvREFCNT_inc(sv_bless(sv_2mortal(newRV_noinc(hv)),
                                  gv_stashpv(classname, TRUE)));
 }
 
-MP_INLINE void *modperl_hash_tied_object(pTHX_ 
-                                         const char *classname,
-                                         SV *tsv)
+MP_INLINE SV *modperl_hash_tied_object_rv(pTHX_ 
+                                          const char *classname,
+                                          SV *tsv)
 {
     if (sv_derived_from(tsv, classname)) {
         if (SVt_PVHV == SvTYPE(SvRV(tsv))) {
@@ -47,7 +65,7 @@
 
             if (SvMAGICAL(hv)) {
                 if ((mg = mg_find(hv, PERL_MAGIC_tied))) {
-                    return (void *)MgObjIV(mg);
+                    return mg->mg_obj;
                 }
                 else {
                     Perl_warn(aTHX_ "Not a tied hash: (magic=%c)", mg);
@@ -58,7 +76,7 @@
             }
         }
         else {
-            return (void *)SvObjIV(tsv);
+            return tsv;
         }
     }
     else {
@@ -67,7 +85,20 @@
                    "(expecting an %s derived object)", classname);
     }
 
-    return NULL;
+    return &PL_sv_undef;
+}
+
+MP_INLINE void *modperl_hash_tied_object(pTHX_ 
+                                         const char *classname,
+                                         SV *tsv)
+{
+    SV *rv = modperl_hash_tied_object_rv(aTHX_ classname, tsv);
+    if (SvROK(rv)) {
+        return (void *)SvIVX(SvRV(rv));
+    }
+    else {
+        return NULL;
+    }
 }
 
 /* same as Symbol::gensym() */
Index: src/modules/perl/modperl_common_util.h
===================================================================
RCS file: /home/cvspublic/modperl-2.0/src/modules/perl/modperl_common_util.h,v
retrieving revision 1.2
diff -u -r1.2 modperl_common_util.h
--- src/modules/perl/modperl_common_util.h	22 Jun 2004 22:34:10 -0000	1.2
+++ src/modules/perl/modperl_common_util.h	13 Jul 2004 06:20:57 -0000
@@ -75,6 +75,10 @@
                                SV *tsv, void *p);
 
 /* tied %hash */
+MP_INLINE SV *modperl_hash_tied_object_rv(pTHX_ 
+                                          const char *classname,
+                                          SV *tsv);
+/* tied %hash */
 MP_INLINE void *modperl_hash_tied_object(pTHX_ const char *classname,
                                          SV *tsv);
 
Index: t/apr-ext/table.t
===================================================================
RCS file: /home/cvspublic/modperl-2.0/t/apr-ext/table.t,v
retrieving revision 1.1
diff -u -r1.1 table.t
--- t/apr-ext/table.t	16 Jun 2004 03:55:48 -0000	1.1
+++ t/apr-ext/table.t	13 Jul 2004 06:20:58 -0000
@@ -1,15 +1,37 @@
+use warnings FATAL => 'all';
+use strict;
+
 use Apache::Test;
+use Apache::TestUtil;
 
 use blib;
 use Apache2;
 
-plan tests => 1;
+plan tests => 15;
+
+use APR;
+use APR::Table;
+use APR::Pool;
 
-require APR;
-require APR::Table;
-require APR::Pool;
 
 my $p = APR::Pool->new;
 
 my $table = APR::Table::make($p, 2);
 ok ref $table eq 'APR::Table';
+
+$table->add("first"  => 1);
+$table->add("second" => 2);
+$table->add("first"  => 3);
+
+my $i = 0;
+while (($a,$b) = each %$table) {
+        my $key = ("first", "second")[$i % 2];
+        my $val = ++$i;
+        ok t_cmp $a,                $key,      "table each: key test";
+        ok t_cmp $b,                $val,      "table each: value test";
+        ok t_cmp $table->{$a},      $val,      "table each: get test";
+        ok t_cmp tied(%$table)->FETCH($a), $val, "table each: tied get test";
+}
+
+ok t_cmp "1,2,3", join(",", values %$table), "table values";
+ok t_cmp "first,1,second,2,first,3", join(",", %$table), "table entries";
Index: xs/APR/Table/APR__Table.h
===================================================================
RCS file: /home/cvspublic/modperl-2.0/xs/APR/Table/APR__Table.h,v
retrieving revision 1.11
diff -u -r1.11 APR__Table.h
--- xs/APR/Table/APR__Table.h	4 Mar 2004 06:01:10 -0000	1.11
+++ xs/APR/Table/APR__Table.h	13 Jul 2004 06:20:59 -0000
@@ -13,7 +13,6 @@
  * limitations under the License.
  */
 
-#define mpxs_APR__Table_FETCH   apr_table_get
 #define mpxs_APR__Table_STORE   apr_table_set
 #define mpxs_APR__Table_DELETE  apr_table_unset
 #define mpxs_APR__Table_CLEAR   apr_table_clear
@@ -122,24 +121,45 @@
 
 static MP_INLINE const char *mpxs_APR__Table_NEXTKEY(pTHX_ SV *tsv, SV *key)
 {
-    apr_table_t *t = mp_xs_sv2_APR__Table(tsv); 
+    apr_table_t *t;
+    SV *rv = modperl_hash_tied_object_rv(aTHX_ "APR::Table", tsv);
+    if (!SvROK(rv)) {
+        Perl_croak(aTHX_ "Usage: $table->NEXTKEY($key): "
+                   "first argument not an APR::Table object");
+    }
+    t = (apr_table_t *)SvIVX(SvRV(rv)); 
 
     if (apr_is_empty_table(t)) {
         return NULL;
     }
-
-    if (mpxs_apr_table_iterix(tsv) < apr_table_elts(t)->nelts) {
-        return mpxs_apr_table_nextkey(t, tsv);
+    if (key == NULL) {
+        mpxs_apr_table_iterix(rv) = 0; /* reset iterator index */
     }
-
+    if (mpxs_apr_table_iterix(rv) < apr_table_elts(t)->nelts) {
+        return mpxs_apr_table_nextkey(t, rv);
+    }
+    mpxs_apr_table_iterix(rv) = 0;
     return NULL;
 }
 
-static MP_INLINE const char *mpxs_APR__Table_FIRSTKEY(pTHX_ SV *tsv)
-{
-    mpxs_apr_table_iterix(tsv) = 0; /* reset iterator index */
+/* Try to shortcut apr_table_get by fetching the key using the current
+ * iterator  (unless it's inactive or points at different key).
+ */
+
+static MP_INLINE const char *mpxs_APR__Table_FETCH(pTHX_ SV *tsv,
+                                                   const char *key)
+{
+    SV* rv = modperl_hash_tied_object_rv(aTHX_ "APR::Table", tsv);
+    const int i = mpxs_apr_table_iterix(rv);
+    apr_table_t *t = (apr_table_t *)SvIVX(SvRV(rv));
+    const apr_array_header_t *arr = apr_table_elts(t);
+    apr_table_entry_t *elts = (apr_table_entry_t *)arr->elts;
 
-    return mpxs_APR__Table_NEXTKEY(aTHX_ tsv, Nullsv);
+    if (i > 0 && i <= arr->nelts && !strcasecmp(key, elts[i-1].key)) {
+        return elts[i-1].val;
+    }
+    else
+        return apr_table_get(t, key);
 }
 
 static XS(MPXS_apr_table_get)
@@ -153,11 +173,11 @@
     mpxs_PPCODE({
         APR__Table t = modperl_hash_tied_object(aTHX_ "APR::Table", ST(0));
         const char *key = (const char *)SvPV_nolen(ST(1));
-    
+
         if (!t) {
             XSRETURN_UNDEF;
         }
-        
+
         if (GIMME_V == G_SCALAR) {
             const char *val = apr_table_get(t, key);
 
@@ -167,9 +187,9 @@
         }
         else {
             const apr_array_header_t *arr = apr_table_elts(t);
-            apr_table_entry_t *elts  = (apr_table_entry_t *)arr->elts;
+            apr_table_entry_t *elts = (apr_table_entry_t *)arr->elts;
             int i;
-            
+
             for (i = 0; i < arr->nelts; i++) {
                 if (!elts[i].key || strcasecmp(elts[i].key, key)) {
                     continue;
Index: xs/maps/apr_functions.map
===================================================================
RCS file: /home/cvspublic/modperl-2.0/xs/maps/apr_functions.map,v
retrieving revision 1.82
diff -u -r1.82 apr_functions.map
--- xs/maps/apr_functions.map	9 Jun 2004 14:46:22 -0000	1.82
+++ xs/maps/apr_functions.map	13 Jul 2004 06:21:00 -0000
@@ -253,12 +253,12 @@
 -apr_table_setn
  apr_table_unset
 -apr_table_vdo
- const char *:DEFINE_FETCH | | apr_table_t *:t, const char *:key
  void:DEFINE_STORE | | apr_table_t *:t, const char *:key, const char *:value
  void:DEFINE_DELETE | | apr_table_t *:t, const char *:key
  void:DEFINE_CLEAR | | apr_table_t *:t
- mpxs_APR__Table_FIRSTKEY
- mpxs_APR__Table_NEXTKEY
+ const char *:DEFINE_FIRSTKEY | mpxs_APR__Table_NEXTKEY | SV *:tsv, SV *:key=Nullsv
+ mpxs_APR__Table_NEXTKEY | | SV *:tsv, SV *:key=&PL_sv_undef
+ mpxs_APR__Table_FETCH
  mpxs_APR__Table_EXISTS
 
 !MODULE=APR::File
Index: xs/tables/current/ModPerl/FunctionTable.pm
===================================================================
RCS file: /home/cvspublic/modperl-2.0/xs/tables/current/ModPerl/FunctionTable.pm,v
retrieving revision 1.171
diff -u -r1.171 FunctionTable.pm
--- xs/tables/current/ModPerl/FunctionTable.pm	12 Jul 2004 08:19:40 -0000	1.171
+++ xs/tables/current/ModPerl/FunctionTable.pm	13 Jul 2004 06:21:05 -0000
@@ -5598,7 +5598,7 @@
   },
   {
     'return_type' => 'const char *',
-    'name' => 'mpxs_APR__Table_FIRSTKEY',
+    'name' => 'mpxs_APR__Table_FETCH',
     'attr' => [
       'static',
       '__inline__'
@@ -5611,6 +5611,10 @@
       {
         'type' => 'SV *',
         'name' => 'tsv'
+      },
+      {
+        'type' => 'const char *',
+        'name' => 'key'
       }
     ]
   },




-- 
Joe Schaefer

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to