Commit f7f568ef authored by jan.koester's avatar jan.koester
Browse files

test

parent cc6afae6
Loading
Loading
Loading
Loading
+96 −70
Original line number Diff line number Diff line
@@ -26,6 +26,9 @@
 *******************************************************************************/

#include <iostream>
#include <algorithm>
#include <memory>
#include <vector>
#include <string>
#include <yaml.h>

@@ -35,7 +38,7 @@
namespace confplus {
    struct YamlStack {
        std::string   anchor;
        YamlStack    *prevel;
        std::unique_ptr<YamlStack> prevel;
    };
};

@@ -64,53 +67,64 @@ void confplus::Yaml::saveConfig(const char *path,const Config *conf){


void confplus::Yaml::loadConfig(const char* path, Config* conf) {
    FILE *fh = fopen(path,"rb");
    yaml_event_type_t type;
    FILE* fh = nullptr;
    yaml_event_type_t type = YAML_NO_EVENT;
    yaml_parser_t parse;
    bool parser_initialized = false;
    std::string key, value;

    // FIX C2362: ystack muss vor dem ersten goto initialisiert werden.
    std::unique_ptr<YamlStack> ystack = nullptr;

    /* Initialize parser */
    if (!yaml_parser_initialize(&parse))
        throw "Failed to initialize parser!";
    parser_initialized = true;

    fh = fopen(path, "rb");
    if (fh == nullptr)
        throw "Failed to open file!";
        goto cleanup; // Springt bei Fehler zum Cleanup

    /* Set input file */
    yaml_parser_set_input_file(&parse, fh);

    YamlStack *ystack=nullptr;

    bool seq = false;
    std::string key,value;
    int pos = 0;
    do {
        yaml_event_t event;
        if (!yaml_parser_parse(&parse, &event))
            break;
            goto cleanup; // Springt bei Parser-Fehler zum Cleanup

        switch (event.type) {
        case YAML_MAPPING_START_EVENT: {
                    YamlStack *cystack=new YamlStack;
                    cystack->prevel=ystack;
                    ystack=cystack;
            std::unique_ptr<YamlStack> cystack = std::make_unique<YamlStack>();
            cystack->prevel = std::move(ystack);
            ystack = std::move(cystack);
            ystack->anchor = key;
            key = value;
                    value.clear();
            value = ""; // FIX: Explizite Zuweisung
        }break;

        case YAML_MAPPING_END_EVENT: {
                if(ystack->prevel){
                    YamlStack *pystack=ystack->prevel;
                    delete ystack;
                    ystack=pystack;
            if (ystack) {
                ystack = std::move(ystack->prevel);
            }
        }break;


        case YAML_SCALAR_EVENT: {
                if(key.empty())
                    std::copy(event.data.scalar.value,event.data.scalar.value+event.data.scalar.length,std::inserter<std::string>(key,std::begin(key)));
                else
                    std::copy(event.data.scalar.value,event.data.scalar.value+event.data.scalar.length,std::inserter<std::string>(value,std::begin(value)));
            // FIX: Sichere String-Extraktion durch direkte Konstruktion.
            std::string temp_data(
                (const char*)event.data.scalar.value,
                event.data.scalar.length
            );

            if (key.empty()) {
                key = temp_data;
            }
            else {
                value = temp_data;
            }
        }break;

        case YAML_SEQUENCE_START_EVENT: {
@@ -121,7 +135,7 @@ void confplus::Yaml::loadConfig(const char *path,Config *conf){
            seq = false;
            key = value;
            pos = 0;
                value.clear();
            value = ""; // FIX: Explizite Zuweisung
        }break;

        default:
@@ -129,18 +143,29 @@ void confplus::Yaml::loadConfig(const char *path,Config *conf){
        }

        if (!key.empty() && !value.empty()) {
            std::vector<std::string> path_segments;
            for (YamlStack* curst = ystack.get(); curst; curst = curst->prevel.get()) {
                path_segments.push_back(curst->anchor);
            }

            // FIX: Korrekte Pfadkonstruktion (Root zu Leaf)
            std::string cname;
            for(YamlStack *curst=ystack; curst; curst=curst->prevel){
                std::string pp=curst->anchor; pp+='/';
                std::copy(pp.begin(),pp.end(),std::inserter<std::string>(cname,std::begin(cname)));
            for (auto it = path_segments.rbegin(); it != path_segments.rend(); ++it) {
                if (!it->empty()) {
                    cname += "/";
                    cname += *it;
                }
            }
            cname += "/";
            cname += key;

            Config::ConfigData* ckey = conf->setKey(cname);
            conf->setValue(ckey, pos, value);
            value.clear();
            value = ""; // FIX: Explizite Zuweisung
            if (!seq) {
                key.clear();
            }else{
                key = ""; // FIX: Explizite Zuweisung
            }
            else {
                ++pos;
            }
        }
@@ -148,16 +173,17 @@ void confplus::Yaml::loadConfig(const char *path,Config *conf){
        yaml_event_delete(&event);
    } while (type != YAML_STREAM_END_EVENT);

cleanup:
    // Garantiertes Cleanup der C-Ressourcen
    if (parser_initialized) {
        yaml_parser_delete(&parse);
    }
    if (fh != nullptr) {
        fclose(fh);

    while(ystack){
        YamlStack *prev=ystack->prevel;
        ystack->prevel=nullptr;
        delete ystack;
        ystack=prev;
    }

    delete ystack;

    // Fehler werfen nur, wenn das ffnen der Datei nach der Parser-Initialisierung fehlschlug
    if (fh == nullptr && parser_initialized) {
        throw "Failed to open file!";
    }
}
 No newline at end of file
+35 −27
Original line number Diff line number Diff line
@@ -120,19 +120,22 @@ confplus::Config::ConfigData *confplus::Config::setKey(const std::string &key){
        if(key[pos]=='/' || key[pos]=='\0'){

            std::string childkey;
            std::copy(&key[start],&key[pos],std::inserter<std::string>(childkey,childkey.begin()));
            std::copy(&key[start], &key[pos], std::back_inserter(childkey));
            start=(pos+1);

            find = existsdat(root_ptr->get(), childkey);

            if (!find) {
                find = createdat(*root_ptr);
                find->Key=childkey;
                if(key.empty()){
                    find->Value=std::make_unique<ConfigValue>(key,pos);
                    find->haveChild=true;
                std::unique_ptr<ConfigData>* current_ptr = root_ptr;

                while (current_ptr->get()) {
                    current_ptr = &current_ptr->get()->nextData;
                }
                ++find->Elements;

                *current_ptr = std::unique_ptr<ConfigData>(new ConfigData); // Konstruktor mit Key/Daten

                find = current_ptr->get();

            }
            root_ptr = &find->Child;
        }
@@ -170,8 +173,6 @@ size_t confplus::Config::ConfigData::getElements() const{

#ifdef Windows
confplus::Config::Config(const std::string &path) {
    firstData = nullptr;

    std::string mpath = CONFIGPATH;

    size_t deli = path.find(':');
@@ -184,7 +185,7 @@ confplus::Config::Config(const std::string &path) {

    std::string confpath = path.substr(deli, path.length() - deli);

	std::cout << "Loading backend: " << mpath << std::endl;
	std::cout << "Loading backend: " << mpath << "Config:" << confpath << std::endl;

    _BackendData = LoadLibrary(TEXT(mpath.c_str()));
    if (!_BackendData) {
@@ -338,36 +339,43 @@ int confplus::Config::getIntValue(confplus::Config::ConfigData* key, size_t pos)
    throw err;
}

// In conf.cpp, replace the entire implementation of confplus::Config::setValue():

void confplus::Config::setValue(confplus::Config::ConfigData* key, size_t pos, const std::string& value) {
    // 1. Check if key is a path (correct)
    // 1. Prfen, ob es sich um einen Pfad handelt
    if (key->haveChild) {
        ConfException err;
        err[ConfException::Error] << "setValue it is a path not key";
        throw err;
    }

    // 2. Bestehenden Wert an 'pos' suchen und aktualisieren
    for (ConfigValue* cur = key->Value.get(); cur; cur = cur->_nextValue.get()) {
        if (cur->_Pos == pos) {
            cur->_Value = value;
            return; // Found and updated existing value
            return; // Gefunden und aktualisiert
        }
    }

    // 3. Wenn der Wert nicht existiert, ihn am Ende anfgen.

    // Fall A: Die Liste ist leer (Kopf ist null).
    if (!key->Value) {
        // Set the head pointer directly
        // Setze den Kopfzeiger direkt
        key->Value = std::make_unique<ConfigValue>(value, pos);
    } else {
        // If the head is not null, traverse the linked list to find the last element
        std::unique_ptr<ConfigValue> *current_ptr = &key->Value->_nextValue;
    }
    else {
        // Fall B: Die Liste ist nicht leer. Finde das letzte Element.

        while (current_ptr->get()) {
            current_ptr = &current_ptr->get()->_nextValue;
        // Verwende einen Raw-Pointer zur Traversierung.
        ConfigValue* last = key->Value.get();

        // Durchlaufe die Kette, solange _nextValue existiert.
        while (last->_nextValue) {
            last = last->_nextValue.get();
        }

        // Set the final unique_ptr<ConfigValue>* in the chain
        *current_ptr = std::make_unique<ConfigValue>(value, pos);
        // Hnge das neue Objekt an den _nextValue-Smart Pointer des letzten Elements an.
        // Der Compiler verwendet hier std::move fr eine sichere Zuweisung.
        last->_nextValue = std::make_unique<ConfigValue>(value, pos);
    }
}