Files
Compsys-2021-Assignments/A1/record.c
Nikolaj 7f22e73b91 A1
2021-09-27 12:36:29 +02:00

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);
}