]>
git.ipfire.org Git - people/ms/libloc.git/blob - src/country.c
2 libloc - A library to determine the location of someone on the Internet
4 Copyright (C) 2019 IPFire Development Team <info@ipfire.org>
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
21 #include <loc/libloc.h>
22 #include <loc/compat.h>
23 #include <loc/country.h>
24 #include <loc/private.h>
36 LOC_EXPORT
int loc_country_new(struct loc_ctx
* ctx
, struct loc_country
** country
, const char* country_code
) {
37 if (!loc_country_code_is_valid(country_code
))
40 struct loc_country
* c
= calloc(1, sizeof(*c
));
44 c
->ctx
= loc_ref(ctx
);
47 c
->code
= strdup(country_code
);
49 DEBUG(c
->ctx
, "Country %s allocated at %p\n", c
->code
, c
);
55 LOC_EXPORT
struct loc_country
* loc_country_ref(struct loc_country
* country
) {
61 static void loc_country_free(struct loc_country
* country
) {
62 DEBUG(country
->ctx
, "Releasing country %s %p\n", country
->code
, country
);
67 if (country
->continent_code
)
68 free(country
->continent_code
);
73 loc_unref(country
->ctx
);
77 LOC_EXPORT
struct loc_country
* loc_country_unref(struct loc_country
* country
) {
78 if (--country
->refcount
> 0)
81 loc_country_free(country
);
86 LOC_EXPORT
const char* loc_country_get_code(struct loc_country
* country
) {
90 LOC_EXPORT
const char* loc_country_get_continent_code(struct loc_country
* country
) {
91 return country
->continent_code
;
94 LOC_EXPORT
int loc_country_set_continent_code(struct loc_country
* country
, const char* continent_code
) {
97 // Free previous value
98 if (country
->continent_code
)
99 free(country
->continent_code
);
101 country
->continent_code
= strdup(continent_code
);
106 LOC_EXPORT
const char* loc_country_get_name(struct loc_country
* country
) {
107 return country
->name
;
110 LOC_EXPORT
int loc_country_set_name(struct loc_country
* country
, const char* name
) {
115 country
->name
= strdup(name
);
120 LOC_EXPORT
int loc_country_cmp(struct loc_country
* country1
, struct loc_country
* country2
) {
121 return strcmp(country1
->code
, country2
->code
);
124 int loc_country_new_from_database_v1(struct loc_ctx
* ctx
, struct loc_stringpool
* pool
,
125 struct loc_country
** country
, const struct loc_database_country_v1
* dbobj
) {
129 loc_country_code_copy(buffer
, dbobj
->code
);
134 // Create a new country object
135 int r
= loc_country_new(ctx
, country
, buffer
);
140 loc_country_code_copy(buffer
, dbobj
->continent_code
);
142 r
= loc_country_set_continent_code(*country
, buffer
);
147 const char* name
= loc_stringpool_get(pool
, be32toh(dbobj
->name
));
149 r
= loc_country_set_name(*country
, name
);
157 loc_country_unref(*country
);
161 int loc_country_to_database_v1(struct loc_country
* country
,
162 struct loc_stringpool
* pool
, struct loc_database_country_v1
* dbobj
) {
164 for (unsigned int i
= 0; i
< 2; i
++) {
165 dbobj
->code
[i
] = country
->code
[i
] ? country
->code
[i
] : '\0';
168 // Add continent code
169 if (country
->continent_code
) {
170 for (unsigned int i
= 0; i
< 2; i
++) {
171 dbobj
->continent_code
[i
] = country
->continent_code
[i
] ? country
->continent_code
[i
] : '\0';
175 // Save the name string in the string pool
176 off_t name
= loc_stringpool_add(pool
, country
->name
? country
->name
: "");
177 dbobj
->name
= htobe32(name
);
182 LOC_EXPORT
int loc_country_code_is_valid(const char* cc
) {
187 // It must be 2 characters long
191 // It must only contain A-Z
192 for (unsigned int i
= 0; i
< 2; i
++) {
193 if (cc
[i
] < 'A' || cc
[i
] > 'Z')