#include <libloc/private.h>
#include <libloc/stringpool.h>
+typedef int (*loc_database_match_as)
+ (struct loc_database* db, uint32_t number, off_t i);
+typedef int (*loc_database_match_country)
+ (struct loc_database* db, const char* code, off_t i);
+
struct loc_database_objects {
char* data;
size_t length;
// Countries
struct loc_database_objects country_objects;
+
+ struct loc_database_callbacks {
+ loc_database_match_as match_as;
+ loc_database_match_country match_country;
+ } callbacks;
};
#define MAX_STACK_DEPTH 256
return 0;
}
+static int loc_database_match_as_v1(struct loc_database* db, uint32_t number, off_t i) {
+ struct loc_database_as_v1* as_v1 = (struct loc_database_as_v1*)loc_database_object(db,
+ &db->as_objects, sizeof(*as_v1), i);
+
+ return htobe32(as_v1->number) - number;
+}
+
+static int loc_database_match_country_v1(struct loc_database* db, const char* code, off_t i) {
+ struct loc_database_country_v1* country_v1 = \
+ (struct loc_database_country_v1*)loc_database_object(db, &db->country_objects, sizeof(*country_v1), i);
+
+ return loc_country_code_cmp(country_v1->code, code);
+}
+
static int loc_database_open(struct loc_database* db, FILE* f) {
int r;
if (r)
return r;
+ // Set the callbacks
+ switch (db->version) {
+ case LOC_DATABASE_VERSION_1:
+ db->callbacks.match_as = loc_database_match_as_v1;
+ db->callbacks.match_country = loc_database_match_country_v1;
+ break;
+
+ default:
+ return -ENOTSUP;
+ }
+
// Map the database into memory
r = loc_database_mmap(db);
if (r)
return r;
}
-static int loc_database_match_as_v1(struct loc_database* db, uint32_t number, off_t i) {
- struct loc_database_as_v1* as_v1 = (struct loc_database_as_v1*)loc_database_object(db,
- &db->as_objects, sizeof(*as_v1), i);
-
- return htobe32(as_v1->number) - number;
-}
-
// Performs a binary search to find the AS in the list
LOC_EXPORT int loc_database_get_as(struct loc_database* db, struct loc_as** as, uint32_t number) {
int r;
+ // Fail if the callback has not been set
+ if (!db->callbacks.match_as)
+ return -ENOTSUP;
+
off_t lo = 0;
off_t hi = db->as_objects.count - 1;
off_t i = (lo + hi) / 2;
// Match the AS number
- r = loc_database_match_as_v1(db, number, i);
+ r = db->callbacks.match_as(db, number, i);
if (r < 0) {
lo = i + 1;
return r;
}
-static int loc_database_match_country_v1(struct loc_database* db, const char* code, int i) {
- struct loc_database_country_v1* country_v1 = \
- (struct loc_database_country_v1*)loc_database_object(db, &db->country_objects, sizeof(*country_v1), i);
-
- return loc_country_code_cmp(country_v1->code, code);
-}
-
// Performs a binary search to find the country in the list
LOC_EXPORT int loc_database_get_country(struct loc_database* db,
struct loc_country** country, const char* code) {
return 1;
}
+ // Fail if the callback has not been set
+ if (!db->callbacks.match_country)
+ return -ENOTSUP;
+
#ifdef ENABLE_DEBUG
// Save start time
clock_t start = clock();
off_t i = (lo + hi) / 2;
// Match the country code
- r = loc_database_match_country_v1(db, code, i);
+ r = db->callbacks.match_country(db, code, i);
if (r < 0) {
lo = i + 1;