aboutsummaryrefslogtreecommitdiff
path: root/flx/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'flx/output.c')
-rw-r--r--flx/output.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/flx/output.c b/flx/output.c
new file mode 100644
index 0000000..7898fc8
--- /dev/null
+++ b/flx/output.c
@@ -0,0 +1,157 @@
+#include <string.h>
+#include "utils.h"
+#include "flx.h"
+#include "output.h"
+#include "source_type.h"
+#include "flx_fcntl.h"
+
+int Sorted = (INPUT_SORTED|OUTPUT_SORTED); /* input/output sorted status */
+
+t_file_desc *free_file_desc(t_file_desc *desc) {
+ if (!desc) return (NULL);
+ if (desc->md5) FREE(desc->md5);
+ if (desc->link) FREE(desc->link);
+ FREE(desc);
+ return (NULL);
+}
+
+t_file_desc *fct_free_file_desc(void *data, t_file_desc *desc) {
+ return (free_file_desc(desc));
+}
+
+/* this function free file tree and return 1 if the free is completed
+ * it doesn't free the element (base)
+ */
+int ft_free(t_ft *tree, void *(*fct_free)(void *data, void *desc), void *data) {
+ t_ft *next;
+
+ /* nothing have change, do not free */
+ if (IS(Sorted, OUTPUT_SORTED) && !IS(Sorted, INPUT_SORTED)) return (0);
+
+ /* remove description */
+ if (IS(tree->status, FILLED)) {
+ if (tree->desc && fct_free) tree->desc = fct_free(data, tree->desc);
+ UNSET(tree->status, FILLED);
+ }
+ /* check for recursion */
+ if (!IS(tree->status, CHANGED) || IS(tree->status, SORTING) || !tree->subtree) {
+ UNSET(tree->status, CHANGED);
+ return (1);
+ }
+ /* look for first soon */
+ tree = tree->subtree->next;
+
+ while (!IS(tree->status, BASE)) {
+
+ /* pass unchanged elements */
+ if (!IS(tree->status, CHANGED)) { tree = tree->next; continue ; }
+
+ /* unset filled and remove data */
+ if (IS(tree->status, FILLED)) {
+ if (tree->desc && fct_free) tree->desc = fct_free(data, tree->desc);
+ UNSET(tree->status, FILLED);
+ }
+ /* stop if necessary */
+ if (IS(Sorted, OUTPUT_SORTED) && IS(tree->status, SORTING))
+ return (0);
+
+ /* check if having to look at subtree */
+ if (tree->subtree && !IS_PDOTF(tree)) {
+ if (ft_free(tree, fct_free, data)) {
+ if (tree->subtree == tree->subtree->next)
+ POOL_FREE(t_file_tree, tree->subtree);
+ }
+ else return (0);
+ }
+ /* free filename memory */
+ if (tree->filename) FREE(tree->filename);
+ /* unchain and go to the next */
+ next = tree->next;
+ UNSET(tree->status, CHANGED);
+ if (fct_free) {
+ LIST_UNCHAIN(tree);
+ POOL_FREE(t_file_tree, tree);
+ }
+ tree = next;
+ }
+ return (1);
+}
+
+int output_write(t_db_output *out, void *data, int number) {
+ t_device *dst;
+ void *current;
+ int valid = 1;
+
+ for (current = out->outputs; current ; current = SIMPLE_LIST_NEXT(current)) {
+ dst = SIMPLE_LIST_PTR(current);
+ if (dst->opened->write)
+ valid = dst->opened->write(dst->env, data, number) && valid;
+ }
+ return (valid);
+}
+
+int output_add(t_db_output *out, char *desc, t_source_type *sourcestype) {
+ char tmp[BUFFER_LENGTH], *ptmp, *otmp = NULL;
+ int i;
+ t_device *new;
+
+ strcpy(tmp, desc);
+ if ((ptmp = backslashed_strchr(tmp, ':'))) {
+ *ptmp++ = 0;
+
+ /* look for options */
+ if ((otmp = strchr(tmp, '+'))) *otmp++ = 0;
+
+ /* find corresponding source */
+ for (i = 0; sourcestype[i].name; i++)
+ if (!strcmp(tmp, sourcestype[i].name)) break;
+ if (!sourcestype[i].name) {
+ /* not found, error */
+ error("can't find source type %s (%s:%s)", tmp, tmp, ptmp);
+ return (0);
+ }
+ }
+ else {
+ error("no source type specified");
+ return (0);
+ }
+
+ /* allocate memory for new device */
+ new = MALLOC(sizeof(*new));
+ new->opened = &sourcestype[i];
+ if (new->opened->open) {
+ if (!(new->env = new->opened->open(ptmp, otmp))) {
+ error("can't open '%s'", desc);
+ FREE(new);
+ return (0);
+ }
+ if (new->opened->fcntl)
+ Sorted |= (new->opened->fcntl(new->env, IS_SORTED) ? OUTPUT_SORTED : 0);
+ }
+ else
+ new->env = NULL;
+ SIMPLE_LIST_PUSH(out->outputs, new);
+ return (1);
+}
+
+t_db_output *output_alloc() {
+ t_db_output *out;
+
+ out = MALLOC(sizeof(*out));
+ bzero(out, sizeof(*out));
+ return (out);
+}
+
+t_db_output *output_free(t_db_output *old) {
+ t_device *dst;
+
+ while (old->outputs) {
+ dst = SIMPLE_LIST_POP(old->outputs);
+ if (dst->opened->close)
+ dst->opened->close(dst->env);
+ FREE(dst);
+ }
+ FREE(old);
+ return (NULL);
+}
+