kml-parser 0.1.1

K(refting) M(ulti) L(anguage) Parser
Documentation
#include "read.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

/**
 * @brief Überprüft, ob die Datei die Endung .kml hat
 * @param filename Der Dateiname zur Überprüfung
 * @return true, wenn die Datei die Endung .kml hat, sonst false
 * <div rustbindgen private>
*/
bool _suffix_check(char* filename) {
    char* suffix = strrchr(filename, '.');
    if (suffix == NULL) {
        return false;
    } else if (strcmp(suffix, ".kml") != 0) {
        return false;
    }
    return true;
} 

/**
 * @brief Überprüft, ob die Datei existiert
 * @param filename Der Dateiname zur Überprüfung
 * @return true, wenn die Datei existiert, sonst false
 * <div rustbindgen private>
*/
bool _file_exists(char* filename) {
    FILE* file = fopen(filename, "r");
    if (file == NULL) {
        return false;
    }
    fclose(file);
    return true;
}


/**
 * @brief Ermittelt die Größe der Datei
 * @param filename Der Dateiname zur Überprüfung
 * @return Die Größe der Datei
 * <div rustbindgen private>
*/
float _file_size(char* filename) {
    FILE* file = fopen(filename, "r");
    fseek(file, 0, SEEK_END);
    float size = ftell(file);
    fclose(file);
    return size;
} /** <div rustbindgen private="false"></div> */



/**
 * @brief Liest die Größe der kml-Datei
 * @param filename Der Dateiname zur Überprüfung
 * @return Die Größe der Datei
*/
float read_kml_size(char* filename) {
    return _file_size(filename);
}

/**
 * @brief Liest die Version der kml-Datei
 * @param filename Der Dateiname zur Überprüfung
 * @return Die Version der Datei
*/
float read_kml_version(char* filename) {
    /* Die Version muss in der 5. Zeile gesetzt sein */
    FILE* file = fopen(filename, "r");
    if (file == NULL) {
        return 0.0;
    }

    char line[256];
    for (int i = 0; i < 5; i++) {
        if (fgets(line, sizeof(line), file) == NULL) {
            fclose(file);
            return 0.0;
        }
    }

    const char* needed_begin = "&kml_set_version<";
    const char* needed_end = ">&";
    char* start = strstr(line, needed_begin);
    char* end = strstr(line, needed_end);

    if (start != NULL && end != NULL && start < end) {
        start += strlen(needed_begin);
        *end = '\0';
        float version = atof(start);
        fclose(file);
        return version;
    }

    fclose(file);
    return 0.0;
}

/**
 * @brief Liest den Namen der kml-Datei
 * @param filename Der Dateiname zur Überprüfung
 * @return Der Name der Datei
*/
char* read_kml_name(char* filename) {
    /* Der Name muss in der 6. Zeile gesetzt sein */
    FILE* file = fopen(filename, "r");
    if (file == NULL) {
        return NULL;
    }

    char line[256];
    for (int i = 0; i < 6; i++) {
        if (fgets(line, sizeof(line), file) == NULL) {
            fclose(file);
            return NULL;
        }
    }

    const char* needed_begin = "&kml_set_name<";
    const char* needed_end = ">&";
    char* start = strstr(line, needed_begin);
    char* end = strstr(line, needed_end);

    if (start != NULL && end != NULL && start < end) {
        start += strlen(needed_begin);
        *end = '\0';
        fclose(file);
        return strdup(start);
    }

    fclose(file);
    return NULL;
}

/**
 * @brief Liest die Beschreibung der kml-Datei
 * @param filename Der Dateiname zur Überprüfung
 * @return Die Beschreibung der Datei
*/
char* read_kml_description(char* filename) {
    /* Die Beschreibung muss in der 7. Zeile gesetzt sein */
    FILE* file = fopen(filename, "r");
    if (file == NULL) {
        return NULL;
    }

    char line[256];
    for (int i = 0; i < 7; i++) {
        if (fgets(line, sizeof(line), file) == NULL) {
            fclose(file);
            return NULL;
        }
    }

    const char* needed_begin = "&kml_set_description<";
    const char* needed_end = ">&";
    char* start = strstr(line, needed_begin);
    char* end = strstr(line, needed_end);

    if (start != NULL && end != NULL && start < end) {
        start += strlen(needed_begin);
        *end = '\0';
        fclose(file);
        return strdup(start);
    }

    fclose(file);
    return NULL;
}

/**
 * @brief Liest den Autor der kml-Datei
 * @param filename Der Dateiname zur Überprüfung
 * @return Der Autor der Datei
*/
char* read_kml_author(char* filename) {
    /* Der Autor muss in der 8. Zeile gesetzt sein */
    FILE* file = fopen(filename, "r");
    if (file == NULL) {
        return NULL;
    }

    char line[256];
    for (int i = 0; i < 8; i++) {
        if (fgets(line, sizeof(line), file) == NULL) {
            fclose(file);
            return NULL;
        }
    }

    const char* needed_begin = "&kml_set_author<";
    const char* needed_end = ">&";
    char* start = strstr(line, needed_begin);
    char* end = strstr(line, needed_end);

    if (start != NULL && end != NULL && start < end) {
        start += strlen(needed_begin);
        *end = '\0';
        fclose(file);
        return strdup(start);
    }

    fclose(file);
    return NULL;
}

/**
 * @brief Liest die Abhängigkeiten der kml-Datei
 * @param filename Der Dateiname zur Überprüfung
 * @return Die Abhängigkeiten der Datei
*/
char* read_kml_depends(char* filename) {
    /* Die Abhängigkeiten müssen in der 9. Zeile gesetzt sein */
    FILE* file = fopen(filename, "r");
    if (file == NULL) {
        return NULL;
    }

    char line[256];
    for (int i = 0; i < 9; i++) {
        if (fgets(line, sizeof(line), file) == NULL) {
            fclose(file);
            return NULL;
        }
    }

    const char* needed_begin = "&kml_set_depends<";
    const char* needed_end = ">&";
    char* start = strstr(line, needed_begin);
    char* end = strstr(line, needed_end);

    if (start != NULL && end != NULL && start < end) {
        start += strlen(needed_begin);
        *end = '\0';
        fclose(file);
        return strdup(start);
    }

    fclose(file);
    return NULL;
}

/**
 * @brief Liest den Inhalt der kml-Datei
 * @param filename Der Dateiname zur Überprüfung
 * @return Der Inhalt der Datei
*/
char* read_kml_file(char* filename) {
    FILE* file = fopen(filename, "r");
    if (file == NULL) {
        return NULL;
    }

    // Gehe zum Ende der Datei, um die Größe zu ermitteln
    fseek(file, 0, SEEK_END);
    long file_size = ftell(file);
    rewind(file);

    // Speicher für den gesamten Inhalt der Datei plus null-terminator
    char* content = (char*)malloc((file_size + 1) * sizeof(char));
    if (content == NULL) {
        fclose(file);
        return NULL;
    }

    // Lese den gesamten Inhalt der Datei
    size_t read_size = fread(content, sizeof(char), file_size, file);
    content[read_size] = '\0'; // Null-terminator hinzufügen

    fclose(file);
    return content;
}

/**
 * @brief Validiert die kml-Datei
 * @param filename Der Dateiname zur Überprüfung
 * @return true, wenn die Datei gültig ist, sonst false
*/
bool validate_kml_file(char* filename) {
    bool val1 = _suffix_check(filename);
    bool val2 = _file_exists(filename);
    bool val3 = (read_kml_version(filename) != 0.0);
    bool val4 = (read_kml_name(filename) != NULL);
    bool val5 = (read_kml_description(filename) != NULL);
    bool val6 = (read_kml_author(filename) != NULL);
    bool val7 = (read_kml_depends(filename) != NULL);

    if (val1 && val2 && val3 && val4 && val5 && val6 && val7) {
        return true;
    } else {
        return false;
    }
}