--- Net-SNMP-XS/XS.xs 2010/05/05 20:46:09 1.12 +++ Net-SNMP-XS/XS.xs 2014/09/18 02:58:42 1.15 @@ -24,7 +24,7 @@ #define HAVE_VERSIONSORT defined (_GNU_SOURCE) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 static SV *cur_bufobj; -static SV *msg; +static SV *msg, *bufsv; static int errflag, leading_dot; static U8 *buf, *cur; static STRLEN len, rem; @@ -47,7 +47,7 @@ #endif static void -switch_bufobj (BUFOBJ neu) +clear_bufobj (void) { // serialise our state back if (msg && SvROK (msg)) @@ -57,18 +57,28 @@ } SvREFCNT_dec (msg); + msg = 0; + cur_bufobj = 0; +} + +static void +switch_bufobj (BUFOBJ neu) +{ + clear_bufobj (); + msg = newSVsv (neu); cur_bufobj = SvRV (msg); sv_rvweaken (msg); - SV *bufsv = *hv_fetch ((HV *)cur_bufobj, "_buffer", sizeof ("_buffer") - 1, 1); - IV index = SvIV (*hv_fetch ((HV *)cur_bufobj, "_index" , sizeof ("_index" ) - 1, 1)); - errflag = 0; leading_dot = -1; - buf = SvPVbyte (bufsv, len); - cur = buf + index; - rem = len - index; + + IV index = SvIV (*hv_fetch ((HV *)cur_bufobj, "_index" , sizeof ("_index" ) - 1, 1)); + bufsv = *hv_fetch ((HV *)cur_bufobj, "_buffer", sizeof ("_buffer") - 1, 1); + + buf = SvPVbyte (bufsv, len); + cur = buf + index; + rem = len - index; } ///////////////////////////////////////////////////////////////////////////// @@ -388,7 +398,7 @@ default: { - if (type > AvFILLp (av_type) || !SvTYPE (AvARRAY (av_type)[type]) == SVt_PVCV) + if (type > AvFILLp (av_type) || SvTYPE (AvARRAY (av_type)[type]) != SVt_PVCV) { error ("Unknown ASN.1 type"); return &PL_sv_undef; @@ -439,15 +449,32 @@ CODE: av_store (av_type, type, SvREFCNT_inc (x_get_cv (cv))); -void -set_msg (SV *msg_, SV *buf_) - CODE: +MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::Message void -clr_msg () - CODE: +_buffer_append (BUFOBJ self, SV *value) + ALIAS: + _buffer_put = 1 + PPCODE: +{ + STRLEN vlen; + const char *vstr = SvPVbyte (value, vlen); -MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::Message + if (ix) + sv_insert (bufsv, 0, 0, vstr, vlen); + else + sv_catpvn (bufsv, vstr, vlen); + + buf = SvPVbyte (bufsv, len); + cur = buf; + rem = len; + + SV *len_sv = *hv_fetch ((HV *)cur_bufobj, "_length", sizeof ("_length") - 1, 1); + sv_setiv (len_sv, len); + + // some callers test for defined'ness of the returnvalue. *sigh* + XPUSHs (&PL_sv_yes); +} void _buffer_get (BUFOBJ self, int count = -1) @@ -458,9 +485,13 @@ { hv_delete ((HV *)SvRV (self), "_index" , 6, G_DISCARD); hv_delete ((HV *)SvRV (self), "_length", 7, G_DISCARD); - SV **svp = hv_fetch ((HV *)SvRV (self), "_buffer", 7, 1); - XPUSHs (sv_2mortal (newSVsv (*svp))); - sv_setpvn (*svp, "", 0); + XPUSHs (sv_2mortal (newSVsv (bufsv))); + sv_setpvn (bufsv, "", 0); + + buf = ""; + cur = buf; + rem = 0; + XSRETURN (1); } @@ -640,8 +671,8 @@ XSRETURN_NO; STRLEN blen, olen; - char *base = SvPV (base_, blen); - char *oid = SvPV (oid_ , olen); + char *base = SvPVbyte (base_, blen); + char *oid = SvPVbyte (oid_ , olen); blen -= *base == '.'; base += *base == '.'; olen -= *base == '.'; oid += *oid == '.';