Net-BART

 view release on metacpan or  search on metacpan

lib/Net/BART/XS.xs  view on Meta::CPAN

    }
    return is_ipv6;
}


MODULE = Net::BART::XS    PACKAGE = Net::BART::XS

PROTOTYPES: DISABLE

SV*
new(class)
    const char *class
  CODE:
    bart_table_t *t = bart_table_new();
    SV *obj = newSViv(PTR2IV(t));
    SV *objref = newRV_noinc(obj);
    sv_bless(objref, gv_stashpv(class, GV_ADD));
    RETVAL = objref;
  OUTPUT:
    RETVAL

void
DESTROY(self)
    SV *self
  CODE:
    bart_table_t *t = INT2PTR(bart_table_t*, SvIV(SvRV(self)));
    free_node_svs(aTHX_ t->root4);
    free_node_svs(aTHX_ t->root6);
    bart_table_free(t);

int
insert(self, prefix_str, value)
    SV *self
    const char *prefix_str
    SV *value
  CODE:
    bart_table_t *t = INT2PTR(bart_table_t*, SvIV(SvRV(self)));
    uint8_t addr[16];
    int addr_len, prefix_len;
    int is_ipv6 = parse_prefix_str(aTHX_ prefix_str, addr, &addr_len, &prefix_len);
    bart_node_t *root = is_ipv6 ? t->root6 : t->root4;

    SV *sv_copy = newSVsv(value);
    void *old_val = NULL;
    int is_new = bart_insert(root, addr, addr_len, prefix_len, 0, (void*)sv_copy, &old_val);

    if (!is_new && old_val) {
        SvREFCNT_dec((SV*)old_val);
    }
    if (is_new) {
        if (is_ipv6) t->size6++; else t->size4++;
    }
    RETVAL = is_new;
  OUTPUT:
    RETVAL

void
lookup(self, ip_str)
    SV *self
    const char *ip_str
  PPCODE:
    bart_table_t *t = INT2PTR(bart_table_t*, SvIV(SvRV(self)));
    uint8_t addr[16];
    int is_ipv6 = parse_ip_str(aTHX_ ip_str, addr);
    int found = 0;
    void *val = bart_lookup(t, addr, is_ipv6, &found);
    if (found && val) {
        XPUSHs(sv_2mortal(newSVsv((SV*)val)));
        XPUSHs(sv_2mortal(newSViv(1)));
    } else {
        XPUSHs(&PL_sv_undef);
        XPUSHs(sv_2mortal(newSViv(0)));
    }

int
contains(self, ip_str)
    SV *self
    const char *ip_str
  CODE:
    bart_table_t *t = INT2PTR(bart_table_t*, SvIV(SvRV(self)));
    uint8_t addr[16];
    int is_ipv6 = parse_ip_str(aTHX_ ip_str, addr);
    RETVAL = bart_contains(t, addr, is_ipv6);
  OUTPUT:
    RETVAL

void
get(self, prefix_str)
    SV *self
    const char *prefix_str
  PPCODE:
    bart_table_t *t = INT2PTR(bart_table_t*, SvIV(SvRV(self)));
    uint8_t addr[16];
    int addr_len, prefix_len;
    int is_ipv6 = parse_prefix_str(aTHX_ prefix_str, addr, &addr_len, &prefix_len);
    int found = 0;
    void *val = bart_get(t, addr, prefix_len, is_ipv6, &found);
    if (found && val) {
        XPUSHs(sv_2mortal(newSVsv((SV*)val)));
        XPUSHs(sv_2mortal(newSViv(1)));
    } else {
        XPUSHs(&PL_sv_undef);
        XPUSHs(sv_2mortal(newSViv(0)));
    }

void
delete(self, prefix_str)
    SV *self
    const char *prefix_str
  PPCODE:
    bart_table_t *t = INT2PTR(bart_table_t*, SvIV(SvRV(self)));
    uint8_t addr[16];
    int addr_len, prefix_len;
    int is_ipv6 = parse_prefix_str(aTHX_ prefix_str, addr, &addr_len, &prefix_len);
    bart_node_t *root = is_ipv6 ? t->root6 : t->root4;
    int found = 0;
    void *val = bart_delete(root, addr, prefix_len, 0, &found);
    if (found) {
        if (is_ipv6) t->size6--; else t->size4--;
        if (val) {
            XPUSHs(sv_2mortal(newSVsv((SV*)val)));
            SvREFCNT_dec((SV*)val);
        } else {
            XPUSHs(&PL_sv_undef);
        }
        XPUSHs(sv_2mortal(newSViv(1)));
    } else {
        XPUSHs(&PL_sv_undef);
        XPUSHs(sv_2mortal(newSViv(0)));
    }

int
size(self)
    SV *self
  CODE:
    bart_table_t *t = INT2PTR(bart_table_t*, SvIV(SvRV(self)));
    RETVAL = t->size4 + t->size6;
  OUTPUT:
    RETVAL

int
size4(self)
    SV *self
  CODE:
    bart_table_t *t = INT2PTR(bart_table_t*, SvIV(SvRV(self)));
    RETVAL = t->size4;
  OUTPUT:
    RETVAL

int
size6(self)
    SV *self
  CODE:
    bart_table_t *t = INT2PTR(bart_table_t*, SvIV(SvRV(self)));
    RETVAL = t->size6;
  OUTPUT:
    RETVAL



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