Commit 32b16159 authored by Michael Tremer's avatar Michael Tremer

country: Refactor storing country code and continent code

Signed-off-by: default avatarMichael Tremer <michael.tremer@ipfire.org>
parent 198e382c
...@@ -35,12 +35,16 @@ static const struct loc_special_country { ...@@ -35,12 +35,16 @@ static const struct loc_special_country {
{ "", 0 }, { "", 0 },
}; };
#define CC_LEN 3
struct loc_country { struct loc_country {
struct loc_ctx* ctx; struct loc_ctx* ctx;
int refcount; int refcount;
char* code; // Store the country code in a 3 byte buffer. Two bytes for the code, and NULL so
char* continent_code; // that we can use strcmp() and return a pointer.
char code[3];
char continent_code[3];
char* name; char* name;
}; };
...@@ -59,7 +63,8 @@ LOC_EXPORT int loc_country_new(struct loc_ctx* ctx, struct loc_country** country ...@@ -59,7 +63,8 @@ LOC_EXPORT int loc_country_new(struct loc_ctx* ctx, struct loc_country** country
c->ctx = loc_ref(ctx); c->ctx = loc_ref(ctx);
c->refcount = 1; c->refcount = 1;
c->code = strdup(country_code); // Set the country code
loc_country_code_copy(c->code, country_code);
DEBUG(c->ctx, "Country %s allocated at %p\n", c->code, c); DEBUG(c->ctx, "Country %s allocated at %p\n", c->code, c);
*country = c; *country = c;
...@@ -76,12 +81,6 @@ LOC_EXPORT struct loc_country* loc_country_ref(struct loc_country* country) { ...@@ -76,12 +81,6 @@ LOC_EXPORT struct loc_country* loc_country_ref(struct loc_country* country) {
static void loc_country_free(struct loc_country* country) { static void loc_country_free(struct loc_country* country) {
DEBUG(country->ctx, "Releasing country %s %p\n", country->code, country); DEBUG(country->ctx, "Releasing country %s %p\n", country->code, country);
if (country->code)
free(country->code);
if (country->continent_code)
free(country->continent_code);
if (country->name) if (country->name)
free(country->name); free(country->name);
...@@ -94,7 +93,6 @@ LOC_EXPORT struct loc_country* loc_country_unref(struct loc_country* country) { ...@@ -94,7 +93,6 @@ LOC_EXPORT struct loc_country* loc_country_unref(struct loc_country* country) {
return NULL; return NULL;
loc_country_free(country); loc_country_free(country);
return NULL; return NULL;
} }
...@@ -107,13 +105,14 @@ LOC_EXPORT const char* loc_country_get_continent_code(struct loc_country* countr ...@@ -107,13 +105,14 @@ LOC_EXPORT const char* loc_country_get_continent_code(struct loc_country* countr
} }
LOC_EXPORT int loc_country_set_continent_code(struct loc_country* country, const char* continent_code) { LOC_EXPORT int loc_country_set_continent_code(struct loc_country* country, const char* continent_code) {
// XXX validate input // Check for valid input
if (!continent_code || strlen(continent_code) != 2) {
// Free previous value errno = EINVAL;
if (country->continent_code) return 1;
free(country->continent_code); }
country->continent_code = strdup(continent_code); // Store the code
loc_country_code_copy(country->continent_code, continent_code);
return 0; return 0;
} }
...@@ -126,37 +125,36 @@ LOC_EXPORT int loc_country_set_name(struct loc_country* country, const char* nam ...@@ -126,37 +125,36 @@ LOC_EXPORT int loc_country_set_name(struct loc_country* country, const char* nam
if (country->name) if (country->name)
free(country->name); free(country->name);
if (name) if (name) {
country->name = strdup(name); country->name = strdup(name);
// Report error if we could not copy the string
if (!country->name)
return 1;
}
return 0; return 0;
} }
LOC_EXPORT int loc_country_cmp(struct loc_country* country1, struct loc_country* country2) { LOC_EXPORT int loc_country_cmp(struct loc_country* country1, struct loc_country* country2) {
return strcmp(country1->code, country2->code); return strncmp(country1->code, country2->code, 2);
} }
int loc_country_new_from_database_v1(struct loc_ctx* ctx, struct loc_stringpool* pool, int loc_country_new_from_database_v1(struct loc_ctx* ctx, struct loc_stringpool* pool,
struct loc_country** country, const struct loc_database_country_v1* dbobj) { struct loc_country** country, const struct loc_database_country_v1* dbobj) {
char buffer[3]; char buffer[3] = "XX";
// Read country code // Read country code
loc_country_code_copy(buffer, dbobj->code); loc_country_code_copy(buffer, dbobj->code);
// Terminate buffer
buffer[2] = '\0';
// Create a new country object // Create a new country object
int r = loc_country_new(ctx, country, buffer); int r = loc_country_new(ctx, country, buffer);
if (r) if (r)
return r; return r;
// Continent Code // Copy continent code
loc_country_code_copy(buffer, dbobj->continent_code); if (*dbobj->continent_code)
loc_country_code_copy((*country)->continent_code, dbobj->continent_code);
r = loc_country_set_continent_code(*country, buffer);
if (r)
goto FAIL;
// Set name // Set name
const char* name = loc_stringpool_get(pool, be32toh(dbobj->name)); const char* name = loc_stringpool_get(pool, be32toh(dbobj->name));
...@@ -175,20 +173,20 @@ FAIL: ...@@ -175,20 +173,20 @@ FAIL:
int loc_country_to_database_v1(struct loc_country* country, int loc_country_to_database_v1(struct loc_country* country,
struct loc_stringpool* pool, struct loc_database_country_v1* dbobj) { struct loc_stringpool* pool, struct loc_database_country_v1* dbobj) {
off_t name = 0;
// Add country code // Add country code
for (unsigned int i = 0; i < 2; i++) { if (*country->code)
dbobj->code[i] = country->code[i] ? country->code[i] : '\0'; loc_country_code_copy(dbobj->code, country->code);
}
// Add continent code // Add continent code
if (country->continent_code) { if (*country->continent_code)
for (unsigned int i = 0; i < 2; i++) { loc_country_code_copy(dbobj->continent_code, country->continent_code);
dbobj->continent_code[i] = country->continent_code[i] ? country->continent_code[i] : '\0';
}
}
// Save the name string in the string pool // Save the name string in the string pool
off_t name = loc_stringpool_add(pool, country->name ? country->name : ""); if (country->name)
name = loc_stringpool_add(pool, country->name);
dbobj->name = htobe32(name); dbobj->name = htobe32(name);
return 0; return 0;
...@@ -227,7 +225,7 @@ LOC_EXPORT int loc_country_special_code_to_flag(const char* cc) { ...@@ -227,7 +225,7 @@ LOC_EXPORT int loc_country_special_code_to_flag(const char* cc) {
// Return flags for any known special country // Return flags for any known special country
for (const struct loc_special_country* country = loc_special_countries; for (const struct loc_special_country* country = loc_special_countries;
country->flags; country++) { country->flags; country++) {
if (strcmp(country->code, cc) == 0) if (strncmp(country->code, cc, 2) == 0)
return country->flags; return country->flags;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment