static trg_files_tree_node *trg_file_parser_node_insert(trg_files_tree_node * top, trg_files_tree_node * last, JsonObject * file, gint index, JsonArray * enabled, JsonArray * priorities) { gchar **path = g_strsplit(file_get_name(file), "/", -1); trg_files_tree_node *lastIter = last; GList *parentList = NULL; gchar *path_el; GList *li; int i; /* Build up a list of pointers to each parent trg_files_tree_node * reversing the order as it iterates over its parent. */ if (lastIter) while ((lastIter = lastIter->parent)) parentList = g_list_prepend(parentList, lastIter); li = parentList; lastIter = top; /* Iterate over the path list which contains each file/directory * component of the path in order. */ for (i = 0; (path_el = path[i]); i++) { gboolean isFile = !path[i + 1]; trg_files_tree_node *target_node = NULL; /* No point checking for files. If there is a last parents iterator * check it for a shortcut. I'm assuming that these come in order of * directory at least to give performance a boost. */ if (li && !isFile) { trg_files_tree_node *lastPathNode = (trg_files_tree_node *) li->data; if (!g_strcmp0(lastPathNode->name, path[i])) { target_node = lastPathNode; li = g_list_next(li); } else { /* No need to check any further. */ li = NULL; } } if (!target_node && lastIter && lastIter->childrenHash && !isFile) target_node = g_hash_table_lookup(lastIter->childrenHash, path_el); /* Node needs creating */ if (!target_node) { target_node = g_new0(trg_files_tree_node, 1); target_node->name = g_strdup(path[i]); target_node->parent = lastIter; trg_files_tree_node_add_child(lastIter, target_node); } lastIter = target_node; /* Files have more properties set here than for files. * Directories are updated from here too, by trg_files_tree_update_ancestors * working up the parents. */ if (isFile) { target_node->length = file_get_length(file); target_node->bytesCompleted = file_get_bytes_completed(file); target_node->index = index; target_node->enabled = (gint) json_array_get_int_element(enabled, index); target_node->priority = (gint) json_array_get_int_element(priorities, index); trg_files_tree_update_ancestors(target_node); } else { target_node->index = -1; } } g_list_free(parentList); g_strfreev(path); return lastIter; }
static trg_files_tree_node *trg_file_parser_node_insert(trg_files_tree_node * top, trg_files_tree_node * last, be_node * file_node, gint index) { be_node *file_length_node = be_dict_find(file_node, "length", BE_INT); be_node *file_path_list = be_dict_find(file_node, "path", BE_LIST); trg_files_tree_node *lastIter = last; GList *parentList = NULL; be_node *path_el_node; GList *li; int i; if (!file_path_list || !file_length_node) return NULL; if (lastIter) while ((lastIter = lastIter->parent)) parentList = g_list_prepend(parentList, lastIter); li = parentList; lastIter = top; /* Iterate over the path list which contains each file/directory * component of the path in order. */ for (i = 0; (path_el_node = file_path_list->val.l[i]); i++) { gboolean isFile = !file_path_list->val.l[i + 1]; trg_files_tree_node *target_node = NULL; if (li && !isFile) { trg_files_tree_node *lastPathNode = (trg_files_tree_node *) li->data; if (!g_strcmp0(lastPathNode->name, path_el_node->val.s)) { target_node = lastPathNode; li = g_list_next(li); } else { li = NULL; } } if (!target_node && lastIter && lastIter->childrenHash && !isFile) target_node = g_hash_table_lookup(lastIter->childrenHash, path_el_node->val.s); if (!target_node) { target_node = g_new0(trg_files_tree_node, 1); target_node->name = g_strdup(path_el_node->val.s); target_node->parent = lastIter; trg_files_tree_node_add_child(lastIter, target_node); } if (isFile) { target_node->length = (gint64) file_length_node->val.i; while (lastIter) { lastIter->length += target_node->length; lastIter = lastIter->parent; } } target_node->index = isFile ? index : -1; lastIter = target_node; } g_list_free(parentList); return lastIter; }