/* voronoi.c * * Created by Rory Healy (healyr@student.unimelb.edu.au) * Created on 11th September 2021 * Last modified 14th September 2021 * * Contains functions for reading a CSV of watchtower information into an * array of towers. * */ #ifndef TOWERS_HEADER #include "towers.h" #endif #define BASE_10 10 #define MAX_CSV_ENTRY_LEN 512 #define MAX_FIELD_LEN 128 #define NUM_CSV_FIELDS 6 void readATower(char *lineBuffer, tower_t *tower) { /* Stores the current CSV field for the current line */ char *token = strtok(lineBuffer, ","); size_t tokenLength; for (int i = 0; i < NUM_CSV_FIELDS; i++) { tokenLength = strlen(token); switch(i) { /* Cases represent each field in the CSV, and as such are handled * differently. */ case 0: tower->id = malloc(sizeof(char) * tokenLength + 1); checkNullPointer(tower->id); strcpy(tower->id, token); tower->id[tokenLength] = '\0'; break; case 1: tower->postcode = malloc(sizeof(char) * tokenLength + 1); checkNullPointer(tower->postcode); strcpy(tower->postcode, token); tower->postcode[tokenLength] = '\0'; break; case 2: tower->population = strtol(token, NULL, BASE_10); break; case 3: tower->manager = malloc(sizeof(char) * tokenLength + 1); checkNullPointer(tower->manager); strcpy(tower->manager, token); tower->manager[tokenLength] = '\0'; break; case 4: tower->x = strtod(token, NULL); break; case 5: tower->y = strtod(token, NULL); break; } token = strtok(NULL, ","); } } tower_t **readTowers(tower_t **towers, FILE *datasetFile, int *numTowers) { /* Maximum length of a single CSV line (+1 for null char in string) */ size_t lineBufferSize = MAX_CSV_ENTRY_LEN + 1; /* Stores the current line from the CSV */ char *lineBuffer = malloc(lineBufferSize * sizeof(*lineBuffer)); checkNullPointer(lineBuffer); int maxSizetowers = 1; /* Discard the header line, then read the rest of the CSV */ getline(&lineBuffer, &lineBufferSize, datasetFile); while (getline(&lineBuffer, &lineBufferSize, datasetFile) > 0) { /* Ensure there is enough space in the towers array */ if (*numTowers == maxSizetowers) { maxSizetowers *= 2; tower_t **temp = realloc(towers, maxSizetowers * sizeof(*towers)); checkNullPointer(temp); towers = temp; } /* The current tower being filled in with information */ towers[*numTowers] = malloc(sizeof(*towers[*numTowers])); readATower(lineBuffer, towers[*numTowers]); *numTowers += 1; } free(lineBuffer); return towers; } void freeTowers(tower_t **towers, int numTowers) { if (!towers) { return; } for (int i = 0; i < numTowers; i++) { if (towers[i]->id) { free(towers[i]->id); } if (towers[i]->manager) { free(towers[i]->manager); } if (towers[i]->postcode) { free(towers[i]->postcode); } if (towers[i]) { free(towers[i]); } } free(towers); }