ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-SNMP-XS/XS.xs
(Generate patch)

Comparing Net-SNMP-XS/XS.xs (file contents):
Revision 1.8 by root, Thu Apr 9 10:08:25 2009 UTC vs.
Revision 1.12 by root, Wed May 5 20:46:09 2010 UTC

19#define ASN_OPAQUE 0x44 19#define ASN_OPAQUE 0x44
20#define ASN_COUNTER64 0x46 20#define ASN_COUNTER64 0x46
21 21
22#define MAX_OID_STRLEN 4096 22#define MAX_OID_STRLEN 4096
23 23
24#define HAVE_VERSIONSORT defined (_GNU_SOURCE) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
25
26static SV *cur_bufobj;
24static SV *msg; 27static SV *msg;
25static int errflag, leading_dot; 28static int errflag, leading_dot;
26static U8 *buf, *cur; 29static U8 *buf, *cur;
27static STRLEN len, rem; 30static STRLEN len, rem;
28 31
32typedef SV *BUFOBJ;
33
34/////////////////////////////////////////////////////////////////////////////
35
36#if 0
37 if (msg)
38 croak ("recursive invocation of Net::SNMP::XS parser is not supported");
39
40
41void
42clr_msg ()
43 CODE:
44 SvREFCNT_dec (msg); msg = 0;
45 buf = cur = (U8 *)"";
46 len = rem = 0;
47#endif
48
49static void
50switch_bufobj (BUFOBJ neu)
51{
52 // serialise our state back
53 if (msg && SvROK (msg))
54 {
55 SV *idx_sv = *hv_fetch ((HV *)cur_bufobj, "_index" , sizeof ("_index" ) - 1, 1);
56 sv_setiv (idx_sv, cur - buf);
57 }
58
59 SvREFCNT_dec (msg);
60 msg = newSVsv (neu);
61 cur_bufobj = SvRV (msg);
62 sv_rvweaken (msg);
63
64 SV *bufsv = *hv_fetch ((HV *)cur_bufobj, "_buffer", sizeof ("_buffer") - 1, 1);
65 IV index = SvIV (*hv_fetch ((HV *)cur_bufobj, "_index" , sizeof ("_index" ) - 1, 1));
66
67 errflag = 0;
68 leading_dot = -1;
69 buf = SvPVbyte (bufsv, len);
70 cur = buf + index;
71 rem = len - index;
72}
73
74/////////////////////////////////////////////////////////////////////////////
75
29static SV * 76static SV *
30x_get_cv (SV *cb_sv) 77x_get_cv (SV *cb_sv)
31{ 78{
32 HV *st; 79 HV *st;
33 GV *gvp; 80 GV *gvp;
41 88
42static void 89static void
43error (const char *errmsg) 90error (const char *errmsg)
44{ 91{
45 errflag = 1; 92 errflag = 1;
93
94 if (!msg)
95 croak ("Net::SNMP::XS fatal error, parser called without parsing context");
46 96
47 dSP; 97 dSP;
48 PUSHMARK (SP); 98 PUSHMARK (SP);
49 EXTEND (SP, 2); 99 EXTEND (SP, 2);
50 PUSHs (msg); 100 PUSHs (msg);
278 U8 *end = cur + length; 328 U8 *end = cur + length;
279 U32 w = getb (); 329 U32 w = getb ();
280 330
281 static char oid[MAX_OID_STRLEN]; // must be static 331 static char oid[MAX_OID_STRLEN]; // must be static
282 char *app = oid; 332 char *app = oid;
333
334 if (leading_dot < 0)
335 leading_dot = SvTRUE (*hv_fetch ((HV *)SvRV (msg), "_leading_dot", sizeof ("_leading_dot") - 1, 1));
283 336
284 *app = '.'; app += ! ! leading_dot; 337 *app = '.'; app += ! ! leading_dot;
285 app = write_uv (app, (U8)w / 40); 338 app = write_uv (app, (U8)w / 40);
286 *app++ = '.'; 339 *app++ = '.';
287 app = write_uv (app, (U8)w % 40); 340 app = write_uv (app, (U8)w % 40);
354 } 407 }
355 408
356 return errflag ? &PL_sv_undef : res; 409 return errflag ? &PL_sv_undef : res;
357} 410}
358 411
412/////////////////////////////////////////////////////////////////////////////
413
414#if HAVE_VERSIONSORT
415
416static int
417oid_lex_cmp (const void *a_, const void *b_)
418{
419 const char *a = SvPVX (*(SV **)a_);
420 const char *b = SvPVX (*(SV **)b_);
421
422 a += *a == '.';
423 b += *b == '.';
424
425 return strverscmp (a, b);
426}
427
428#endif
429
359MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::XS 430MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::XS
360 431
361PROTOTYPES: ENABLE 432PROTOTYPES: ENABLE
362 433
363BOOT: 434BOOT:
369 av_store (av_type, type, SvREFCNT_inc (x_get_cv (cv))); 440 av_store (av_type, type, SvREFCNT_inc (x_get_cv (cv)));
370 441
371void 442void
372set_msg (SV *msg_, SV *buf_) 443set_msg (SV *msg_, SV *buf_)
373 CODE: 444 CODE:
374{
375 if (msg)
376 croak ("recursive invocation of Net::SNMP::XS parser is not supported");
377
378 errflag = 0;
379 leading_dot = -1;
380 msg = SvREFCNT_inc (msg_);
381 buf = SvPVbyte (buf_, len);
382 cur = buf;
383 rem = len;
384#ifdef BENCHMARK
385 t1 = tstamp ();
386#endif
387}
388 445
389void 446void
390clr_msg () 447clr_msg ()
391 CODE: 448 CODE:
392 SvREFCNT_dec (msg); msg = 0;
393 buf = cur = (U8 *)"";
394 len = rem = 0;
395#ifdef BENCHMARK
396 printf ("%f\n", tstamp () - t1);//D
397#endif
398 449
399MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::Message 450MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::Message
400 451
401void 452void
402_buffer_get (SV *self, int count = -1) 453_buffer_get (BUFOBJ self, int count = -1)
403 PPCODE: 454 PPCODE:
404{ 455{
405 // grrr. 456 // grrr.
406 if (count < 0) 457 if (count < 0)
407 { 458 {
418 if (data) 469 if (data)
419 XPUSHs (sv_2mortal (newSVpvn (data, count))); 470 XPUSHs (sv_2mortal (newSVpvn (data, count)));
420} 471}
421 472
422U32 473U32
423index (SV *self, int ndx = -1) 474index (BUFOBJ self, int ndx = -1)
424 CODE: 475 CODE:
425{ 476{
426 if (ndx >= 0 && ndx < len) 477 if (ndx >= 0 && ndx < len)
427 { 478 {
428 cur = buf + ndx; 479 cur = buf + ndx;
433} 484}
434 OUTPUT: 485 OUTPUT:
435 RETVAL 486 RETVAL
436 487
437U32 488U32
438_process_length (SV *self, ...) 489_process_length (BUFOBJ self, ...)
439 ALIAS: 490 ALIAS:
440 _process_sequence = 0 491 _process_sequence = 0
441 CODE: 492 CODE:
442 RETVAL = process_length (); 493 RETVAL = process_length ();
443 OUTPUT: 494 OUTPUT:
444 RETVAL 495 RETVAL
445 496
446SV * 497SV *
447_process_integer32 (SV *self, ...) 498_process_integer32 (BUFOBJ self, ...)
448 CODE: 499 CODE:
449 RETVAL = process_integer32_sv (); 500 RETVAL = process_integer32_sv ();
450 OUTPUT: 501 OUTPUT:
451 RETVAL 502 RETVAL
452 503
453SV * 504SV *
454_process_counter (SV *self, ...) 505_process_counter (BUFOBJ self, ...)
455 ALIAS: 506 ALIAS:
456 _process_gauge = 0 507 _process_gauge = 0
457 _process_timeticks = 0 508 _process_timeticks = 0
458 CODE: 509 CODE:
459 RETVAL = process_unsigned32_sv (); 510 RETVAL = process_unsigned32_sv ();
461 RETVAL 512 RETVAL
462 513
463#if IVSIZE >= 8 514#if IVSIZE >= 8
464 515
465SV * 516SV *
466_process_counter64 (SV *self, ...) 517_process_counter64 (BUFOBJ self, ...)
467 CODE: 518 CODE:
468 RETVAL = process_unsigned64_sv (); 519 RETVAL = process_unsigned64_sv ();
469 OUTPUT: 520 OUTPUT:
470 RETVAL 521 RETVAL
471 522
472#endif 523#endif
473 524
474SV * 525SV *
475_process_object_identifier (SV *self, ...) 526_process_object_identifier (BUFOBJ self, ...)
476 CODE: 527 CODE:
477 RETVAL = process_object_identifier_sv (); 528 RETVAL = process_object_identifier_sv ();
478 OUTPUT: 529 OUTPUT:
479 RETVAL 530 RETVAL
480 531
481SV * 532SV *
482_process_octet_string (SV *self, ...) 533_process_octet_string (BUFOBJ self, ...)
483 ALIAS: 534 ALIAS:
484 _process_opaque = 0 535 _process_opaque = 0
485 CODE: 536 CODE:
486 RETVAL = process_octet_string_sv (); 537 RETVAL = process_octet_string_sv ();
487 OUTPUT: 538 OUTPUT:
488 RETVAL 539 RETVAL
489 540
490SV * 541SV *
491_process_ipaddress (SV *self, ...) 542_process_ipaddress (BUFOBJ self, ...)
492 CODE: 543 CODE:
493{ 544{
494 U32 length = process_length (); 545 U32 length = process_length ();
495 if (length != 4) 546 if (length != 4)
496 { 547 {
503} 554}
504 OUTPUT: 555 OUTPUT:
505 RETVAL 556 RETVAL
506 557
507SV * 558SV *
508process (SV *self, SV *expected = &PL_sv_undef, SV *found = 0) 559process (BUFOBJ self, SV *expected = &PL_sv_undef, SV *found = 0)
509 CODE: 560 CODE:
510{ 561{
511 int type; 562 int type;
512 563
513 RETVAL = process_sv (&type); 564 RETVAL = process_sv (&type);
522 RETVAL 573 RETVAL
523 574
524MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::PDU 575MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::PDU
525 576
526SV * 577SV *
527_process_var_bind_list (SV *self) 578_process_var_bind_list (BUFOBJ self)
528 CODE: 579 CODE:
529{ 580{
530 if (get8 () != ASN_SEQUENCE) 581 if (get8 () != ASN_SEQUENCE)
531 error ("SEQUENCE expected at beginning of VarBindList"); 582 error ("SEQUENCE expected at beginning of VarBindList");
532 int seqlen = process_length (); 583 int seqlen = process_length ();
534 585
535 HV *list = newHV (); 586 HV *list = newHV ();
536 AV *names = newAV (); 587 AV *names = newAV ();
537 HV *types = newHV (); 588 HV *types = newHV ();
538 589
539 hv_store ((HV *)SvRV (self), "_var_bind_list" , sizeof ("_var_bind_list" ) - 1, newRV_noinc ((SV *)list ), 0); 590 hv_store ((HV *)cur_bufobj, "_var_bind_list" , sizeof ("_var_bind_list" ) - 1, newRV_noinc ((SV *)list ), 0);
540 hv_store ((HV *)SvRV (self), "_var_bind_names", sizeof ("_var_bind_names") - 1, newRV_noinc ((SV *)names), 0); 591 hv_store ((HV *)cur_bufobj, "_var_bind_names", sizeof ("_var_bind_names") - 1, newRV_noinc ((SV *)names), 0);
541 hv_store ((HV *)SvRV (self), "_var_bind_types", sizeof ("_var_bind_types") - 1, newRV_noinc ((SV *)types), 0); 592 hv_store ((HV *)cur_bufobj, "_var_bind_types", sizeof ("_var_bind_types") - 1, newRV_noinc ((SV *)types), 0);
542 593
543 while (cur < end && !errflag) 594 while (cur < end && !errflag)
544 { 595 {
545 // SEQUENCE ObjectName ObjectSyntax 596 // SEQUENCE ObjectName ObjectSyntax
546 if (get8 () != ASN_SEQUENCE) 597 if (get8 () != ASN_SEQUENCE)
556 hv_store_ent (types, oid, newSViv (type), 0); 607 hv_store_ent (types, oid, newSViv (type), 0);
557 hv_store_ent (list , oid, val, 0); 608 hv_store_ent (list , oid, val, 0);
558 av_push (names, oid); 609 av_push (names, oid);
559 } 610 }
560 611
561 //return $this->_report_pdu_error if ($this->{_pdu_type} == REPORT); 612 // sigh - great design to do it here
613 SV *pdu_type = *hv_fetch ((HV *)cur_bufobj, "_pdu_type" , sizeof ("_pdu_type" ) - 1, 1);
614
615 if (SvIV (pdu_type) == 0xa8) // REPORT
616 {
617 PUSHMARK (SP);
618 XPUSHs (msg);
619 PUTBACK;
620 call_method ("_report_pdu_error", G_VOID | G_DISCARD);
621 SPAGAIN;
622 XSRETURN_EMPTY;
623 }
562 624
563 RETVAL = newRV_inc ((SV *)list); 625 RETVAL = newRV_inc ((SV *)list);
564} 626}
565 OUTPUT: 627 OUTPUT:
566 RETVAL 628 RETVAL
567 629
630MODULE = Net::SNMP::XS PACKAGE = Net::SNMP
568 631
632void
633oid_base_match (SV *base_, SV *oid_)
634 PROTOTYPE: $$
635 ALIAS:
636 oid_context_match = 0
637 PPCODE:
638{
639 if (!SvOK (base_) || !SvOK (oid_))
640 XSRETURN_NO;
641
642 STRLEN blen, olen;
643 char *base = SvPV (base_, blen);
644 char *oid = SvPV (oid_ , olen);
645
646 blen -= *base == '.'; base += *base == '.';
647 olen -= *base == '.'; oid += *oid == '.';
648
649 if (olen < blen)
650 XSRETURN_NO;
651
652 if (memcmp (base, oid, blen))
653 XSRETURN_NO;
654
655 if (oid [blen] && oid [blen] != '.')
656 XSRETURN_NO;
657
658 XSRETURN_YES;
659}
660
661#if HAVE_VERSIONSORT
662
663void
664oid_lex_sort (...)
665 PROTOTYPE: @
666 PPCODE:
667{
668 // make sure SvPVX is valid
669 int i;
670 for (i = items; i--; )
671 {
672 SV *sv = ST (i);
673
674 if (SvTYPE (sv) < SVt_PV || SvTYPE (sv) == SVt_PVAV && SvTYPE (sv) == SVt_PVHV)
675 SvPV_force_nolen (sv);
676 }
677
678 qsort (&ST (0), items, sizeof (SV *), oid_lex_cmp);
679
680 EXTEND (SP, items);
681 // we cheat somewhat by not returning copies here
682 for (i = 0; i < items; ++i)
683 PUSHs (sv_2mortal (SvREFCNT_inc (ST (i))));
684}
685
686int
687_index_cmp (const char *a, const char *b)
688 PROTOTYPE: $$
689 CODE:
690 RETVAL = strverscmp (a, b);
691 OUTPUT:
692 RETVAL
693
694#endif
695

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines