After a fun week of machines crashing all over me, here is my first attempt at
a tied implementation of APR::Tables.
Important to note that this will most probably be partly rewritten as I don't believe
it's "the right way" to do it. It does work for me though.
The few things that I believe are not done right are:
1. the tie and untie functions should be macros
2. the T_APRTABLEOBJ typemap stuff is just nasty. The only thing I want to be able
to do
is to define input/output typemap for an APR::Table, and right now I had to
hardcode quite
a few things
3. All the mp_xs_sv2_* macros are completely separate from the typemap entries, and I
think they
should be somehow tied together. Right now I have to
#define mp_xs_sv2_APR__Table(sv) \
_mpxs_apr_table_untie(aTHX_ sv)
if I want to use mpxs_usage_va_2 and friends
4. XS aliases. if apr_table_get and apr_table_FETCH are identical, there should be a
way to simply
alias one to the other instead of duplicating the XS glue
newXS("APR::Table::FETCH", XS_APR__Table_get, file);
is all that's required.
5. FIRSTKEY, NEXTKEY not implemented yet, as I have to figure out a place I can stash
the state of an iterator somwehere.
Somehow I believe these issues are probably already supported by the code generation
stuff, just couldn't find
it at all. Care to point me in the right direction ?
--
Philippe M. Chiasson <[EMAIL PROTECTED]>
Extropia's Resident System Guru
http://www.eXtropia.com/
You can solve any problem by adding a level of
indirection--except the problem of having too many levels
of indirection.
-- Larry Wall
perl -e '$$=\${gozer};{$_=unpack(P26,pack(L,$$));/^Just Another Perl
Hacker!\n$/&&print||$$++&&redo}'
Index: lib/ModPerl/WrapXS.pm
===================================================================
RCS file: /home/anoncvs/mod_perl-2-cvs/lib/ModPerl/WrapXS.pm,v
retrieving revision 1.21
diff -u -I'$Id' -I'$Revision' -r1.21 WrapXS.pm
--- lib/ModPerl/WrapXS.pm 2001/09/13 02:37:37 1.21
+++ lib/ModPerl/WrapXS.pm 2001/09/20 04:52:24
@@ -506,6 +506,7 @@
my %typemap = (
'Apache::RequestRec' => 'T_APACHEOBJ',
'apr_time_t' => 'T_APR_TIME',
+ 'APR::Table' => 'T_APRTABLEOBJ',
);
sub write_typemap {
Index: t/response/TestAPR/table.pm
===================================================================
RCS file: /home/anoncvs/mod_perl-2-cvs/t/response/TestAPR/table.pm,v
retrieving revision 1.2
diff -u -I'$Id' -I'$Revision' -r1.2 table.pm
--- t/response/TestAPR/table.pm 2001/09/15 18:17:31 1.2
+++ t/response/TestAPR/table.pm 2001/09/20 04:52:24
@@ -14,7 +14,7 @@
sub handler {
my $r = shift;
- plan $r, tests => 9;
+ plan $r, tests => 15;
my $table = APR::Table::make($r->pool, 16);
@@ -58,7 +58,24 @@
$filter_count = 0;
$table->do("my_filter", "c", "b", "e");
ok $filter_count == 3;
+
+ #Tied interface
+ {
+ my $table = APR::Table::make($r->pool, $TABLE_SIZE);
+
+ ok (UNIVERSAL::isa($table, 'HASH'));
+
+ ok (UNIVERSAL::isa($table, 'HASH')) && tied(%$table);
+
+ ok $table->{'foo'} = 'bar';
+ ok $table->{'foo'} eq 'bar';
+
+ ok delete $table->{'foo'} || 1;
+
+ ok not exists $table->{'foo'};
+ }
+
Apache::OK;
}
Index: todo/api.txt
===================================================================
RCS file: /home/anoncvs/mod_perl-2-cvs/todo/api.txt,v
retrieving revision 1.4
diff -u -I'$Id' -I'$Revision' -r1.4 api.txt
--- todo/api.txt 2001/09/15 18:17:31 1.4
+++ todo/api.txt 2001/09/20 04:52:24
@@ -5,7 +5,8 @@
tied filehandle interface:
-CLOSE, GETC, PRINTF, READLINE
-APR::Table tie mechanism:
+APR::Table FIRSTKEY/NEXTKEY
+
$r->headers_out->{KEY} is not currently supported
might want to make this optional, disabled by default
Index: xs/typemap
===================================================================
RCS file: /home/anoncvs/mod_perl-2-cvs/xs/typemap,v
retrieving revision 1.4
diff -u -I'$Id' -I'$Revision' -r1.4 typemap
--- xs/typemap 2001/05/04 21:21:49 1.4
+++ xs/typemap 2001/09/20 04:52:25
@@ -8,6 +8,9 @@
T_APACHEOBJ
sv_setref_pv($arg, \"${ntype}\", (void*)$var);
+T_APRTABLEOBJ
+ $arg = _mpxs_apr_table_tie(aTHX_ $arg, $var);
+
T_VPTR
sv_setiv($arg, PTR2IV($var));
@@ -18,6 +21,9 @@
INPUT
T_APACHEOBJ
$var = modperl_xs_sv2request_rec(aTHX_ $arg, \"$ntype\", cv)
+
+T_APRTABLEOBJ
+ $var = _mpxs_apr_table_untie(aTHX_ $arg);
T_APACHEREF
$var = modperl_xs_sv2request_rec(aTHX_ $arg, \"$ntype\", cv)
Index: xs/APR/Table/APR__Table.h
===================================================================
RCS file: /home/anoncvs/mod_perl-2-cvs/xs/APR/Table/APR__Table.h,v
retrieving revision 1.3
diff -u -I'$Id' -I'$Revision' -r1.3 APR__Table.h
--- xs/APR/Table/APR__Table.h 2001/09/19 23:08:07 1.3
+++ xs/APR/Table/APR__Table.h 2001/09/20 04:52:25
@@ -1,3 +1,10 @@
+#define mp_xs_sv2_APR__Table(sv) \
+_mpxs_apr_table_untie(aTHX_ sv)
+
+#define apr_table_FETCH apr_table_get
+#define apr_table_STORE apr_table_set
+#define apr_table_DELETE apr_table_unset
+
typedef struct {
SV *cv;
apr_hash_t *filter;
@@ -6,6 +13,9 @@
typedef int (*mpxs_apr_table_do_cb_t)(void *, const char *, const char *);
+SV* _mpxs_apr_table_tie(pTHX_ SV *, apr_table_t *);
+apr_table_t *_mpxs_apr_table_untie(pTHX_ SV *);
+
static int mpxs_apr_table_do_cb(void *data,
const char *key, const char *val)
{
@@ -84,4 +94,53 @@
/* Free tdata.filter or wait for the pool to go away? */
return;
+}
+
+static
+SV* _mpxs_apr_table_tie(pTHX_ SV *sv, apr_table_t *t)
+{
+ SV *hv = (SV*) newHV();
+ sv_setref_pv(sv,"APR::Table",t);
+ sv_magic(hv, sv, PERL_MAGIC_tied, Nullch, 0);
+ return SvREFCNT_inc(sv_bless(sv_2mortal(newRV_noinc(hv)),gv_stashpv("APR::Table",
+TRUE)));
+}
+
+static
+apr_table_t *_mpxs_apr_table_untie(pTHX_ SV *sv)
+{
+ if (sv_derived_from(sv, "APR::Table")) {
+ if( SVt_PVHV == SvTYPE(SvRV(sv)) )
+ {
+ SV *hv = SvRV(sv);
+ MAGIC *mg;
+
+ if (SvMAGICAL(hv)) {
+ if (mg = mg_find(hv, PERL_MAGIC_tied)) {
+ return (apr_table_t *)SvIV((SV*)SvRV(mg->mg_obj));
+ } else
+ {
+ Perl_warn(aTHX_ "Wrong Magick: (%c)\n", mg);
+ }
+
+ } else
+ {
+ Perl_warn(aTHX_ "Not Magick but should\n");
+ }
+
+ } else
+ {
+ return (apr_table_t *) SvIV((SV*)SvRV(sv));
+ }
+ } else
+ {
+ Perl_croak(aTHX_ "argument is not a blessed reference (expecting an
+APR::Table derived object)");
+ }
+
+ return NULL;
+}
+
+static MP_INLINE
+int apr_table_EXISTS(apr_table_t *t, const char *key)
+{
+ return (NULL==apr_table_get(t,key)) ? 0 : 1;
}
Index: xs/maps/apr_functions.map
===================================================================
RCS file: /home/anoncvs/mod_perl-2-cvs/xs/maps/apr_functions.map,v
retrieving revision 1.21
diff -u -I'$Id' -I'$Revision' -r1.21 apr_functions.map
--- xs/maps/apr_functions.map 2001/09/17 01:06:08 1.21
+++ xs/maps/apr_functions.map 2001/09/20 04:52:25
@@ -191,7 +191,15 @@
-apr_table_setn
apr_table_unset
-apr_table_vdo
-
+ apr_table_FETCH
+ apr_table_STORE
+ apr_table_DELETE
+ apr_table_CLEAR
+ apr_table_EXISTS
+-apr_table_KEYS
+-apr_table_FIRSTKEY
+-apr_table_NEXTKEY
+
!MODULE=APR::File
-apr_file_open
-apr_file_close
PGP signature