#import "geolocation_city.h" static const char *_value_or_unknown(const char *ptr) { return ptr ? ptr : "Unknown"; } static VALUE rb_city_initialize(VALUE rb_module, VALUE location) { file_location = STR2CSTR(location); } static VALUE rb_city_set_file_location(VALUE rb_module, VALUE location) { file_location = STR2CSTR(location); } static VALUE rb_city_get_file_location(VALUE rb_module) { return rb_str_new2(file_location); } static VALUE rb_city_from_ip(VALUE rb_module, VALUE host) { GeoIP *gi; GeoIPRecord *gir; VALUE city; gi = GeoIP_open(file_location, GEOIP_INDEX_CACHE); if (gi == NULL) { rb_raise(rb_eRuntimeError, "Unable to open geolocation file."); } gir = GeoIP_record_by_name(gi, STR2CSTR(host)); if (gir != NULL) { city = rb_str_new2(_value_or_unknown(gir->city)); GeoIPRecord_delete(gir); } else { city = rb_str_new2("Unknown"); } GeoIP_delete(gi); return city; } static VALUE rb_city_to_s(VALUE rb_module) { char buf[256]; sprintf(buf, "#<%s:%p file_location=\"%s\">", rb_obj_classname(rb_module), (void*)rb_module, file_location); return rb_str_new(buf, strlen(buf)); } void Init_geolocation_city() { rb_mGeolocation = rb_define_module("Geolocation"); rb_cCity = rb_define_class_under(rb_mGeolocation, "City", rb_cObject); rb_define_method(rb_cCity, "initialize", rb_city_initialize, 1); rb_define_method(rb_cCity, "file_location=", rb_city_set_file_location, 1); rb_define_method(rb_cCity, "file_location", rb_city_get_file_location, 0); rb_define_method(rb_cCity, "from_ip", rb_city_from_ip, 1); rb_define_method(rb_cCity, "to_s", rb_city_to_s, 0); }