IP-Geolocation-MMDB
view release on metacpan or search on metacpan
CODE:
if ((items - 1) % 2 != 0) {
warn("Odd-length list passed to %" SVf " constructor", SVfARG(klass));
}
for (i = 1; i < items; i += 2) {
key = SvPV_nolen_const(ST(i));
value = ST(i + 1);
if (strEQ(key, "file")) {
file = value;
}
}
if (NULL == file) {
croak("The \"file\" parameter is mandatory");
}
filename = SvPVbyte_nolen(file);
Newxz(self, 1, struct ip_geolocation_mmdb);
storeTHX(self->perl);
self->file = SvREFCNT_inc(file);
mmdb_error = MMDB_open(filename, flags, &self->mmdb);
if (MMDB_SUCCESS != mmdb_error) {
Safefree(self);
error = MMDB_strerror(mmdb_error);
croak("Error opening database file \"%" SVf "\": %s", SVfARG(file),
error);
}
RETVAL = sv_bless(newRV_noinc(newSViv(PTR2IV(self))),
gv_stashsv(klass, GV_ADD));
self->selfrv = SvRV(RETVAL); /* no inc */
OUTPUT:
RETVAL
void
DESTROY(self)
IP::Geolocation::MMDB self
CODE:
MMDB_close(&self->mmdb);
SvREFCNT_dec(self->file);
Safefree(self);
void
get(self, ...)
IP::Geolocation::MMDB self
ALIAS:
record_for_address = 1
INIT:
const char *ip_address;
int gai_error, mmdb_error;
const char *error;
MMDB_lookup_result_s result;
MMDB_entry_data_list_s *list;
SV *data = &PL_sv_undef;
int wants_prefix_length = 0;
uint16_t prefix_length = 0;
U8 gimme = GIMME_V;
PPCODE:
ip_address = NULL;
if (items > 1) {
ip_address = SvPVbyte_nolen(ST(1));
}
if (NULL == ip_address || '\0' == *ip_address) {
croak("%s", "You must provide an IP address to look up");
}
result =
MMDB_lookup_string(&self->mmdb, ip_address, &gai_error, &mmdb_error);
if (0 != gai_error) {
croak("The IP address you provided (%s) is not a valid IPv4 or IPv6 "
"address", ip_address);
}
if (MMDB_SUCCESS != mmdb_error) {
error = MMDB_strerror(mmdb_error);
croak("Error looking up IP address \"%s\": %s", ip_address, error);
}
if (result.found_entry) {
list = NULL;
mmdb_error = MMDB_get_entry_data_list(&result.entry, &list);
if (MMDB_SUCCESS == mmdb_error) {
(void) decode_entry_data_list(self, list, &data, &mmdb_error);
}
MMDB_free_entry_data_list(list);
if (MMDB_SUCCESS != mmdb_error) {
error = MMDB_strerror(mmdb_error);
croak("Entry data error looking up \"%s\": %s", ip_address,
error);
}
if (0 == ix && G_SCALAR != gimme) {
wants_prefix_length = 1;
if (instr(ip_address, ".") && is_ipv6_database(&self->mmdb)) {
prefix_length = result.netmask - 96;
}
else {
prefix_length = result.netmask;
}
}
}
XPUSHs(sv_2mortal(data));
if (wants_prefix_length) {
XPUSHs(sv_2mortal(newSVuv(prefix_length)));
}
void
iterate_search_tree(self, ...)
IP::Geolocation::MMDB self
INIT:
SV *data_callback;
SV *node_callback;
iterate_data data;
numeric_ip ipnum;
CODE:
data_callback = &PL_sv_undef;
node_callback = &PL_sv_undef;
if (items > 1) {
data_callback = ST(1);
if (items > 2) {
node_callback = ST(2);
}
( run in 0.744 second using v1.01-cache-2.11-cpan-71847e10f99 )