--- Net-SNMP-XS/XS.xs 2009/04/08 10:39:32 1.2 +++ Net-SNMP-XS/XS.xs 2009/04/08 13:54:42 1.3 @@ -25,13 +25,26 @@ #define ASN_EXTENSION_ID 0x1f #define ASN_BIT8 0x80 -//#define BENCHMARK +#define BENCHMARK static SV *msg; static int errflag; static U8 *buf, *cur; static STRLEN len, rem; +static SV * +x_get_cv (SV *cb_sv) +{ + HV *st; + GV *gvp; + CV *cv = sv_2cv (cb_sv, &st, &gvp, 0); + + if (!cv) + croak ("CODE reference expected"); + + return (SV *)cv; +} + static void error (const char *msg) { @@ -136,8 +149,20 @@ return res; } +static AV *av_type; + MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::XS +PROTOTYPES: ENABLE + +BOOT: + av_type = newAV (); + +void +set_type (int type, SV *cv) + CODE: + av_store (av_type, type, SvREFCNT_inc (x_get_cv (cv))); + void set_msg (SV *msg_, SV *buf_) CODE: @@ -201,7 +226,7 @@ U32 _process_length (SV *self, ...) ALIAS: - _process_sequence = 1 + _process_sequence = 0 CODE: RETVAL = process_length (); OUTPUT: @@ -308,3 +333,42 @@ OUTPUT: RETVAL +SV * +process (SV *self, SV *expected = 0, SV *found = 0) + PPCODE: +{ + U8 type = get8 (); + + if (expected && SvOK (expected) && type != SvIV (expected)) + { + error ("Expected a different type than found"); + XSRETURN_UNDEF; + } + + if (type > AvFILLp (av_type) || !SvTYPE (AvARRAY (av_type)[type]) == SVt_PVCV) + { + sv_dump (AvARRAY (av_type)[type]);//D + error ("Unknown ASN.1 type"); + XSRETURN_UNDEF; + } + + if (found) + sv_setiv (found, type); + + SV *res; + + { + dSP; + PUSHMARK (SP); + EXTEND (SP, 2); + PUSHs (self); + PUSHs (expected); + PUTBACK; + int count = call_sv (AvARRAY (av_type)[type], G_SCALAR); + SPAGAIN; + res = count ? TOPs : &PL_sv_undef; + } + + XPUSHs (res); +} +