bool addServiceNode()

in bundles/http_admin/http_admin/src/service_tree.c [60:163]


bool addServiceNode(service_tree_t *svc_tree, const char *uri, void *svc) {
    char *save_ptr = NULL; //Used internally by strtok_r
    char *uri_cpy = NULL;
    char *req_uri = NULL;
    bool uri_exists = true;
    size_t tokenCount = getUriTokenCount(uri, "/");
    size_t subNodeCount = 1;

    if(svc_tree == NULL || uri == NULL){
        return false;
    }

    if(strcmp(uri, "/") == 0 ) {
        //Create the root URI
        if(svc_tree->root_node == NULL) { //No service yet added
            svc_tree->root_node = createServiceNode(NULL, NULL, NULL, NULL, "root", svc);
            svc_tree->tree_node_count = 1;
            uri_exists = false;
        } else if(strcmp(svc_tree->root_node->svc_data->sub_uri, "root") != 0) {
            service_tree_node_t *node = createServiceNode(NULL, svc_tree->root_node, NULL, NULL, "root", svc);
            //Set this new node as parent for the first line of nodes
            service_tree_node_t *tmp = svc_tree->root_node;
            while(tmp != NULL){
                tmp->parent = node;
                tmp = tmp->next;
            }
            svc_tree->root_node->parent = node;
            svc_tree->root_node = node; //Set new root
            svc_tree->tree_node_count++;
            uri_exists = false;
        }
        //Else root already exists
    } else if(svc_tree->root_node == NULL) { //No service yet added
        uri_cpy = strdup(uri);
        req_uri = strtok_r(uri_cpy, "/", &save_ptr);
        svc_tree->root_node = createServiceNode(NULL, NULL, NULL, NULL, req_uri, (tokenCount == 1 ? svc : NULL));
        svc_tree->tree_node_count = 1;
        uri_exists = false;
    } else if(strcmp(svc_tree->root_node->svc_data->sub_uri, "root") == 0){
        asprintf(&uri_cpy, "%s%s", "root", uri);
        req_uri = strtok_r(uri_cpy, "/", &save_ptr);
    } else {
        uri_cpy = strdup(uri);
        req_uri = strtok_r(uri_cpy, "/", &save_ptr);
    }

    service_tree_node_t *current = svc_tree->root_node;
    service_node_data_t *current_data = current->svc_data;
    while (req_uri != NULL && subNodeCount <= tokenCount) {
        bool is_last_entry = (tokenCount == subNodeCount);
        if (strcmp(current_data->sub_uri, req_uri) == 0) {
            if (is_last_entry) {
                //Entry already exists/added in tree
                if (current_data->service == NULL) {
                    //When no service added yet, add the current. Because there can already be sub URIs registered
                    //as children for this URI. No extra node is added, because the node already exists
                    current_data->service = svc;
                    uri_exists = false;
                }
                req_uri = strtok_r(NULL, "/", &save_ptr);
            } else if (current->children != NULL) {
                //Found the parent of the URI, keep searching in the children for sub URIs
                current = current->children;
                current_data = current->svc_data;
                req_uri = strtok_r(NULL, "/", &save_ptr);
            } else {
                //Parent has no sub URIs registered yet
                req_uri = strtok_r(NULL, "/", &save_ptr);
                //Create svc node without svc pointer, this will be added later if needed.
                service_tree_node_t *node = createServiceNode(current, NULL, NULL, NULL, req_uri, NULL);
                current->children = node;
                current = node;
                current_data = node->svc_data;
                svc_tree->tree_node_count++;
                uri_exists = false;
            }
            subNodeCount++;
        } else if (current->next != NULL) {
            current = current->next;
            current_data = current->svc_data;
        } else {
            //Not found, so create this URI (tree)
            service_tree_node_t *node = createServiceNode(current->parent, NULL, NULL, current,
                                                          req_uri, (is_last_entry ? svc : NULL));
            current->next = node;
            current = node;
            current_data = node->svc_data;
            svc_tree->tree_node_count++;
            uri_exists = false;
            subNodeCount++;
        }
    }

    //Increment tree service count if URI exists (only one service can be added at once)
    if(!uri_exists) {
        svc_tree->tree_svc_count++;
    }

    if(uri_cpy) {
        free(uri_cpy);
    }

    return !uri_exists;
}