175 lines
3.7 KiB
C
175 lines
3.7 KiB
C
#include "record.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
|
|
// Sanity check to make sure we are reading the right kind of file.
|
|
int input_looks_ok(FILE *f) {
|
|
char *line = NULL;
|
|
size_t n;
|
|
if (getline(&line, &n, f) == -1) {
|
|
return -1;
|
|
}
|
|
|
|
int ret;
|
|
if (strcmp(line, "name alternative_names osm_type osm_id class type lon lat place_rank importance street city county state country country_code display_name west south east north wikidata wikipedia housenumbers\n") == 0) {
|
|
ret = 1;
|
|
} else {
|
|
ret = 0;
|
|
}
|
|
|
|
free(line);
|
|
return ret;
|
|
}
|
|
|
|
// Read a single record from an open file. This is pretty tedious, as
|
|
// we handle each field explicitly.
|
|
int read_record(struct record *r, FILE *f) {
|
|
char *line = NULL;
|
|
size_t n;
|
|
if (getline(&line, &n, f) == -1) {
|
|
free(line);
|
|
return -1;
|
|
}
|
|
|
|
r->line = line;
|
|
|
|
char* start = line;
|
|
char* end;
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->name = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->alternative_names = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->osm_type = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->osm_id = atol(start); *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->class = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->type = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->lon = atof(start); *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->lat = atof(start); *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->place_rank = atoi(start); *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->importance = atof(start); *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->street = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->city = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->county = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->state = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->country = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->country_code = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->display_name = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->west = atof(start); *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->west = atof(start); *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->east = atof(start); *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->north = atof(start); *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->wikidata = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->wikipedia = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
if ((end = strstr(start, "\t"))) {
|
|
r->housenumbers = start; *end = 0; start = end+1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct record* read_records(const char *filename, int *n) {
|
|
FILE *f = fopen(filename, "r");
|
|
*n = 0;
|
|
|
|
if (f == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
if (!input_looks_ok(f)) {
|
|
return NULL;
|
|
}
|
|
|
|
int capacity = 100;
|
|
int i = 0;
|
|
struct record *rs = malloc(capacity * sizeof(struct record));
|
|
while (read_record(&rs[i], f) == 0) {
|
|
i++;
|
|
if (i == capacity) {
|
|
capacity *= 2;
|
|
rs = realloc(rs, capacity * sizeof(struct record));
|
|
}
|
|
}
|
|
|
|
*n = i;
|
|
fclose(f);
|
|
return rs;
|
|
}
|
|
|
|
void free_records(struct record *rs, int n) {
|
|
for (int i = 0; i < n; i++) {
|
|
free(rs[i].line);
|
|
}
|
|
free(rs);
|
|
}
|