X-Git-Url: http://git.ipfire.org/?p=people%2Fms%2Flibloc.git;a=blobdiff_plain;f=src%2Fwriter.c;fp=src%2Fwriter.c;h=bf3d2bb9faa3c42a8c9a96f06c4052540daa6f55;hp=eb2b2e6dcc5e1bd46733d41f2c665688ff0d8e5b;hb=ec684c1afb72e51f735c81446deb6430ea2dbd6b;hpb=0a56a83edb68a4e1cb03d943651e7409be290d43 diff --git a/src/writer.c b/src/writer.c index eb2b2e6..bf3d2bb 100644 --- a/src/writer.c +++ b/src/writer.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,9 @@ struct loc_writer { struct loc_as** as; size_t as_count; + struct loc_country** countries; + size_t countries_count; + struct loc_network_tree* networks; }; @@ -183,6 +187,32 @@ LOC_EXPORT int loc_writer_add_network(struct loc_writer* writer, struct loc_netw return loc_network_tree_add_network(writer->networks, *network); } +static int __loc_country_cmp(const void* country1, const void* country2) { + return loc_country_cmp(*(struct loc_country**)country1, *(struct loc_country**)country2); +} + +LOC_EXPORT int loc_writer_add_country(struct loc_writer* writer, struct loc_country** country, const char* country_code) { + int r = loc_country_new(writer->ctx, country, country_code); + if (r) + return r; + + // We have a new country to add + writer->countries_count++; + + // Make space + writer->countries = realloc(writer->countries, sizeof(*writer->countries) * writer->countries_count); + if (!writer->countries) + return -ENOMEM; + + // Add as last element + writer->countries[writer->countries_count - 1] = loc_country_ref(*country); + + // Sort everything + qsort(writer->countries, writer->countries_count, sizeof(*writer->countries), __loc_country_cmp); + + return 0; +} + static void make_magic(struct loc_writer* writer, struct loc_database_magic* magic) { // Copy magic bytes for (unsigned int i = 0; i < strlen(LOC_DATABASE_MAGIC); i++) @@ -408,6 +438,31 @@ static int loc_database_write_networks(struct loc_writer* writer, return 0; } +static int loc_database_write_countries(struct loc_writer* writer, + struct loc_database_header_v0* header, off_t* offset, FILE* f) { + DEBUG(writer->ctx, "Countries section starts at %jd bytes\n", *offset); + header->countries_offset = htobe32(*offset); + + size_t countries_length = 0; + + struct loc_database_country_v0 country; + for (unsigned int i = 0; i < writer->countries_count; i++) { + // Convert country into database format + loc_country_to_database_v0(writer->countries[i], writer->pool, &country); + + // Write to disk + *offset += fwrite(&country, 1, sizeof(country), f); + countries_length += sizeof(country); + } + + DEBUG(writer->ctx, "Countries section has a length of %zu bytes\n", countries_length); + header->countries_length = htobe32(countries_length); + + align_page_boundary(offset, f); + + return 0; +} + LOC_EXPORT int loc_writer_write(struct loc_writer* writer, FILE* f) { struct loc_database_magic magic; make_magic(writer, &magic); @@ -457,6 +512,11 @@ LOC_EXPORT int loc_writer_write(struct loc_writer* writer, FILE* f) { if (r) return r; + // Write countries + r = loc_database_write_countries(writer, &header, &offset, f); + if (r) + return r; + // Write the header r = fseek(f, sizeof(magic), SEEK_SET); if (r)