com_select(): Improve message.
[paraslash.git] / afh_recv.c
index b76c405a47c686ad5eec5d0e4c569101ff83738a..6525209bff4119a177eb443f154b4f1f5224845b 100644 (file)
@@ -1,8 +1,4 @@
-/*
- * Copyright (C) 2011 Andre Noll <maan@tuebingen.mpg.de>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
+/* Copyright (C) 2011 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
 
 /** \file afh_recv.c Receiver for streaming local files. */
 
@@ -31,6 +27,7 @@ struct private_afh_recv_data {
        long unsigned last_chunk;
        struct timeval stream_start;
        uint32_t current_chunk;
+       void *afh_context;
 };
 
 static int afh_execute(struct btr_node *btrn, const char *cmd, char **result)
@@ -58,7 +55,8 @@ static int afh_execute(struct btr_node *btrn, const char *cmd, char **result)
                        return ret;
                if (x >= pard->afhi.chunks_total)
                        return -ERRNO_TO_PARA_ERROR(EINVAL);
-               pard->first_chunk = afh_get_start_chunk(x, &pard->afhi);
+               pard->first_chunk = afh_get_start_chunk(x, &pard->afhi,
+                       pard->audio_format_num);
                pard->current_chunk = pard->first_chunk;
                return 1;
        }
@@ -70,7 +68,7 @@ static int afh_recv_open(struct receiver_node *rn)
        struct lls_parse_result *lpr = rn->lpr;
        struct private_afh_recv_data *pard;
        struct afh_info *afhi;
-       const char *fn = RECV_CMD_OPT_STRING_VAL(AFH, FILENAME, lpr);
+       const char *fn = RECV_CMD_OPT_STRING_VAL(AFH, FILENAME, lpr), *msg;
        int32_t bc = RECV_CMD_OPT_INT32_VAL(AFH, BEGIN_CHUNK, lpr);
        const struct lls_opt_result *r_e = RECV_CMD_OPT_RESULT(AFH, END_CHUNK, lpr);
        int ret;
@@ -89,18 +87,22 @@ static int afh_recv_open(struct receiver_node *rn)
                goto out_unmap;
        pard->audio_format_num = ret;
        ret = -ERRNO_TO_PARA_ERROR(EINVAL);
+       msg = "no data chunks";
        if (afhi->chunks_total == 0)
                goto out_clear_afhi;
+       msg = "invalid begin chunk";
        if (PARA_ABS(bc) >= afhi->chunks_total)
                goto out_clear_afhi;
        if (bc >= 0)
-               pard->first_chunk = afh_get_start_chunk(bc, &pard->afhi);
+               pard->first_chunk = afh_get_start_chunk(bc, &pard->afhi,
+                       pard->audio_format_num);
        else
                pard->first_chunk = afh_get_start_chunk(afhi->chunks_total + bc,
-                       &pard->afhi);
+                       &pard->afhi, pard->audio_format_num);
        if (lls_opt_given(r_e)) {
                int32_t ec = lls_int32_val(0, r_e);
                ret = -ERRNO_TO_PARA_ERROR(EINVAL);
+               msg = "invalid end chunk";
                if (PARA_ABS(ec) > afhi->chunks_total)
                        goto out_clear_afhi;
                if (ec >= 0)
@@ -110,12 +112,14 @@ static int afh_recv_open(struct receiver_node *rn)
        } else
                pard->last_chunk = afhi->chunks_total - 1;
        ret = -ERRNO_TO_PARA_ERROR(EINVAL);
+       msg = "begin chunk >= end chunk!?";
        if (pard->first_chunk >= pard->last_chunk)
                goto out_clear_afhi;
        pard->current_chunk = pard->first_chunk;
        return pard->audio_format_num;
 out_clear_afhi:
        clear_afhi(afhi);
+       PARA_ERROR_LOG("%s: %s\n", fn, msg);
 out_unmap:
        para_munmap(pard->map, pard->map_size);
        close(pard->fd);
@@ -134,6 +138,7 @@ static void afh_recv_close(struct receiver_node *rn)
        clear_afhi(&pard->afhi);
        para_munmap(pard->map, pard->map_size);
        close(pard->fd);
+       afh_close(pard->afh_context, pard->audio_format_num);
        freep(&rn->private_data);
 }
 
@@ -167,7 +172,7 @@ static int afh_recv_post_select(__a_unused struct sched *s, void *context)
        struct afh_info *afhi = &pard->afhi;
        int ret;
        char *buf;
-       const char *start, *end;
+       const char *start;
        size_t size;
        struct timeval chunk_time;
        unsigned j_given = RECV_CMD_OPT_GIVEN(AFH, JUST_IN_TIME, lpr);
@@ -189,11 +194,16 @@ static int afh_recv_post_select(__a_unused struct sched *s, void *context)
                }
        }
        if (!j_given) {
-               afh_get_chunk(pard->first_chunk, afhi, pard->map, &start, &size);
-               afh_get_chunk(pard->last_chunk, afhi, pard->map, &end, &size);
-               end += size;
-               PARA_INFO_LOG("adding %td bytes\n", end - start);
-               btr_add_output_dont_free(start, end - start, btrn);
+               long unsigned n;
+               for (n = pard->first_chunk; n < pard->last_chunk; n++) {
+                       ret = afh_get_chunk(n, afhi, pard->audio_format_num,
+                               pard->map, pard->map_size, &start, &size,
+                               &pard->afh_context);
+                       if (ret < 0)
+                               goto out;
+                       PARA_DEBUG_LOG("adding %zu bytes\n", size);
+                       btr_add_output_dont_free(start, size, btrn);
+               }
                ret = -E_RECV_EOF;
                goto out;
        }
@@ -206,7 +216,12 @@ static int afh_recv_post_select(__a_unused struct sched *s, void *context)
                if (ret > 0)
                        goto out;
        }
-       afh_get_chunk(pard->current_chunk, afhi, pard->map, &start, &size);
+       ret = afh_get_chunk(pard->current_chunk, afhi,
+               pard->audio_format_num, pard->map,
+               pard->map_size, &start, &size,
+               &pard->afh_context);
+       if (ret < 0)
+               goto out;
        PARA_DEBUG_LOG("adding chunk %u\n", pard->current_chunk);
        btr_add_output_dont_free(start, size, btrn);
        if (pard->current_chunk >= pard->last_chunk) {
@@ -223,6 +238,7 @@ out:
        return ret;
 }
 
+/** See \ref recv_init(). */
 const struct receiver lsg_recv_cmd_com_afh_user_data = {
        .init = afh_init,
        .open = afh_recv_open,