Net-IP-Match-Bin

 view release on metacpan or  search on metacpan

Bin.xs  view on Meta::CPAN

  parse_net4(str, len, &addr, &mask);
  /* _inet_aton2(ip, &addr); */
  m_addr = 0;
  p = ctx->root;
  /*
  _dump(p, m_addr, 0);
  m_addr = 0;
  */
  for (i=0; i<=mask; i++) {
    if (p->code != NULL) {
	/*
      printf("p->code: %s(%x) mask=%d i=%d \n", p->code, p->code, mask, i);
	*/
      if (match != NULL && *match != NULL) {
	if (p->code == (char *)(-1)) {
	   print_ip(m_addr, i, match);
	} else {
	   *match = p->code;
	}
      }
      return 1;
    }
    if (addr & bits[i]) {
      m_addr |= bits[i];
      if (p->one) {
	p = p->one;
	continue;
      }
    } else {
      if (p->zero) {
	p = p->zero;
	continue;
      }
    }
	/*
    print_ip(m_addr, i, &str);
    printf("||| mask=%d i=%d where=%s one(%p) zero(%p) code(%p)\n", mask, i, str, p->one, p->zero, p->code);
	*/
    return 0;
  }
	/*
  print_ip(m_addr, i, &str);
  printf(">>> mask=%d i=%d where=%s one(%p) zero(%p) code(%p)\n", mask, i, str, p->one, p->zero, p->code);
	*/
  return 0;
}

MODULE = Net::IP::Match::Bin		PACKAGE = Net::IP::Match::Bin

PROTOTYPES: DISABLE

void
new(class, ...)
    SV* class

    PREINIT:
        XS2_CTX* ctx;
	SV* sv;
	int i;

    PPCODE:
        STRLEN len;
        char *sclass = SvPV(class, len);
#if PVER >= 5008008
        Newx(ctx, 1, XS2_CTX);
#else
        Newz(0, ctx, 1, XS2_CTX);
#endif
        if (init(aTHX_ ctx) != 1) {
            Safefree(ctx);
            XSRETURN_UNDEF;
	} else {
	    for (i=1; i<items; i++) {
		if (SvROK(ST(i))) {
		    sv = SvRV(ST(i));
		} else {
		    sv = ST(i);
		}
		if (_add(aTHX_ ctx, sv) < 0) {
		  Safefree(ctx);
		  XSRETURN_UNDEF;
		}
	    }

            ST(0) = sv_newmortal();
            sv_setref_pv(ST(0), sclass, ctx);
            XSRETURN(1);
        }

void
add(self, ...)
     SV* self

     PREINIT:
	XS2_CTX* ctx;
	SV* sv;
	int i;

     PPCODE:
	if (!SvROK(self)) {
	    XSRETURN_UNDEF;
	} else {
	    ctx = INT2PTR(XS2_CTX*, SvIV(SvRV(self)));
	}
	if (items < 2) {
	    /* too few args */
	    XSRETURN_UNDEF;
	}
	for (i=1; i<items; i++) {
	    if (SvROK(ST(i))) {
                sv = SvRV(ST(i));
            } else {
                sv = ST(i);
            }
	    if (_add(aTHX_ ctx, sv)<0) {
	      Safefree(ctx);
	      XSRETURN_UNDEF;
	    }
	}
	ST(0) = newSVsv(self);
	sv_2mortal(ST(0));
	XSRETURN(1);
	/*XSRETURN_YES;*/

void
add_range(self, ...)
     SV* self

     PREINIT:
	XS2_CTX* ctx;
	SV* sv;
	int i;

     PPCODE:
	if (!SvROK(self)) {
	    XSRETURN_UNDEF;
	} else {
	    ctx = INT2PTR(XS2_CTX*, SvIV(SvRV(self)));
	}
	if (items < 2) {
	    /* too few args */
	    XSRETURN_UNDEF;
	}
	for (i=1; i<items; i++) {
	    if (SvROK(ST(i))) {
                sv = SvRV(ST(i));
            } else {
                sv = ST(i);
            }
	    if (_add_range(aTHX_ ctx, sv) < 0) {
	      Safefree(ctx);
	      XSRETURN_UNDEF;
	    }
	}
	ST(0) = newSVsv(self);
	sv_2mortal(ST(0));
	XSRETURN(1);
	/*XSRETURN_YES;*/

void
DESTROY(self)
	SV* self
     CODE:
	if (SvROK(self)) {
	  XS2_CTX* ctx = INT2PTR(XS2_CTX*, SvIV(SvRV(self)));
	  free_m(aTHX_ ctx);
	  Safefree(ctx);
	}

void
match_ip(...)
     PREINIT:
	XS2_CTX* ctx;
	char *ip;
	SV* net;
	STRLEN len;
	char out[21];
	char *p;
	int i;
	SV* sv;
	int func_call;
	int res;
     PPCODE:
	if (items < 2) {
	    /* too few args */
	    XSRETURN_UNDEF;
	}
	if (!SvROK(ST(0))) {
	    /* can be called as function */
#if PVER >= 5008008
	    Newx(ctx, 1, XS2_CTX);
#else
	    Newz(0, ctx, 1, XS2_CTX);
#endif
            if (init(aTHX_ ctx) != 1) {
		Safefree(ctx);
		XSRETURN_UNDEF;
	    }
	    i = 0;
	    func_call = 1;
	} else {
	    ctx = INT2PTR(XS2_CTX*, SvIV(SvRV(ST(0))));
	    i = 1;
	    func_call = 0;
	}
	ip = SvPVbyte(ST(i), len);
	if (SvROK(ST(i))) {
	    net = SvRV(ST(i));
	} else {
	    net = ST(i);
	}

	/* printf("%s\n", ip); */
	
	i++;
	for (; i<items; i++) {
	    if (SvROK(ST(i))) {
		sv = SvRV(ST(i));
	    } else {
		sv = ST(i);
	    }
	    if (_add(aTHX_ ctx, sv) < 0) {
	      Safefree(ctx);
	      XSRETURN_UNDEF;
	    }
	}

	p = out;
	_clean(aTHX_ ctx);
	res = _match_ip(aTHX_ ctx, net, &p);
	if (func_call > 0) {
	  free_m(aTHX_ ctx);
	  Safefree(ctx);
	}
	if (res > 0) {
	  ST(0) = newSVpv(p, 0);
	  sv_2mortal(ST(0));
	  XSRETURN(1);
	} else {
	  XSRETURN_UNDEF;
	}

void
list(self)
     SV* self

     PREINIT:
	XS2_CTX* ctx;
        AV* out;
        I32 i;

     PPCODE:
	I32 gimme = GIMME_V;
	I32 len = 0;

	if (!SvROK(self)) {
	    XSRETURN_UNDEF;
	} else {
	    if (gimme == G_VOID)
		XSRETURN_EMPTY;
	    
	    ctx = INT2PTR(XS2_CTX*, SvIV(SvRV(self)));
	    out = newAV();
	    _clean(aTHX_ ctx);
	    _list(out, ctx->root, 0, 0);
	    switch(gimme) {
	    case G_SCALAR:
		ST(0) = newRV((SV *)out);
		sv_2mortal(ST(0));
		len = 1;
		break;

	    default:
		len = av_len(out) + 1;
		EXTEND(SP, len+1);
		for (i = 0; i < len; i++) {
		    ST(i) = sv_2mortal(av_shift(out));
		}
		break;
	    }
	}
	XSRETURN(len);

void
clean(self)
     SV* self

     PREINIT:
	XS2_CTX* ctx;

     PPCODE:
	if (!SvROK(self)) {
	    XSRETURN_UNDEF;
	} else {
	    ctx = INT2PTR(XS2_CTX*, SvIV(SvRV(self)));
	    _clean(aTHX_ ctx);
	}
	XSRETURN_YES;

void
dump(self)
     SV* self

     PREINIT:
	XS2_CTX* ctx;

     PPCODE:
	if (!SvROK(self)) {
	    XSRETURN_UNDEF;
	} else {
	    ctx = INT2PTR(XS2_CTX*, SvIV(SvRV(self)));
	    _clean(aTHX_ ctx);
	    _dump(ctx->root, 0, 0);
	}
	XSRETURN_YES;



( run in 1.419 second using v1.01-cache-2.11-cpan-5511b514fd6 )