simplify vss_read_chunk()
authorAndre Noll <maan@systemlinux.org>
Sun, 4 Mar 2007 22:22:43 +0000 (23:22 +0100)
committerAndre Noll <maan@systemlinux.org>
Sun, 4 Mar 2007 22:22:43 +0000 (23:22 +0100)
All its parameters are known globally within vss.c, so omit them.
Also, return an int instead of the pointer to the inbuffer which is
also known to the caller.

This patch also introduces para_fseek() in fd.c which is used by
mp3.c and vss.c and changes the mp3 audio format handler so that it
uses the new function and always check the return value.

error.h
fd.c
fd.h
mp3_afh.c
vss.c

diff --git a/error.h b/error.h
index 537aca5..45485e1 100644 (file)
--- a/error.h
+++ b/error.h
@@ -264,8 +264,6 @@ extern const char **para_errlist[];
 
 
 #define MP3_AFH_ERRORS \
-       PARA_ERROR(FREAD, "fread error"), \
-       PARA_ERROR(FSEEK, "fseek error"), \
        PARA_ERROR(FRAME, "invalid mp3 frame"), \
        PARA_ERROR(FRAME_LENGTH, "invalid frame length"), \
        PARA_ERROR(MP3_NO_FILE, "invalid mp3 file pointer"), \
@@ -303,6 +301,7 @@ extern const char **para_errlist[];
 #define VSS_ERRORS \
        PARA_ERROR(AUDIO_FORMAT, "audio format not recognized"), \
        PARA_ERROR(FSTAT, "failed to fstat() audio file"), \
+       PARA_ERROR(EMPTY_CHUNK, "empty chunk"), \
 
 
 #define AFS_ERRORS \
@@ -401,6 +400,8 @@ extern const char **para_errlist[];
        PARA_ERROR(F_GETFL, "failed to get fd flags"), \
        PARA_ERROR(F_SETFL, "failed to set fd flags"), \
        PARA_ERROR(FGETS, "fgets error"), \
+       PARA_ERROR(FSEEK, "fseek error"), \
+       PARA_ERROR(FREAD, "fread error"), \
 
 
 #define WRITE_ERRORS \
diff --git a/fd.c b/fd.c
index d53a3b4..df7921b 100644 (file)
--- a/fd.c
+++ b/fd.c
@@ -141,7 +141,7 @@ __must_check int para_fread(void *dest, size_t nbytes, size_t nmemb, FILE *strea
        return -E_FREAD;
 }
 /**
-* paraslash's wrapper for fgets(3)  
+* paraslash's wrapper for fgets(3)
 * \param line pointer to the buffer to store the line
 * \param size the size of the buffer given by \a line
 * \param f the stream to read from
@@ -166,3 +166,9 @@ again:
        clearerr(f);
        goto again;
 }
+
+int para_fseek(FILE *stream, long offset, int whence)
+{
+       int ret = fseek(stream, offset, whence);
+       return ret < 0? -E_FSEEK : ret;
+}
diff --git a/fd.h b/fd.h
index 6cb3cba..5ae3331 100644 (file)
--- a/fd.h
+++ b/fd.h
@@ -26,3 +26,4 @@ void para_fd_set(int fd, fd_set *fds, int *max_fileno);
 __must_check int para_fread(void *dest, size_t nbytes, size_t nmemb,
                FILE *stream);
 __must_check int para_fgets(char *line, int size, FILE *f);
+int para_fseek(FILE *stream, long offset, int whence);
index 691f1f0..4eaad08 100644 (file)
--- a/mp3_afh.c
+++ b/mp3_afh.c
@@ -252,7 +252,7 @@ static int get_header(FILE *file, struct mp3header *header)
  */
 static int mp3_seek_next_header(void)
 {
-       int k, l = 0, c, first_len;
+       int k, l = 0, c, first_len, ret;
        struct mp3header h, h2;
        long valid_start = 0;
 
@@ -266,17 +266,22 @@ static int mp3_seek_next_header(void)
                first_len = get_header(infile, &h);
                if (first_len <= 0)
                        continue;
-               if (fseek(infile, first_len - FRAME_HEADER_SIZE, SEEK_CUR) < 0)
-                       return -E_FSEEK;
+               ret = para_fseek(infile, first_len - FRAME_HEADER_SIZE, SEEK_CUR);
+               if (ret < 0)
+                       return ret;
                for (k = 1; k < MIN_CONSEC_GOOD_FRAMES; k++) {
                        if ((l = get_header(infile, &h2)) <= 0)
                                break;
                        if (!compare_headers(&h, &h2))
                                break;
-                       fseek(infile, l - FRAME_HEADER_SIZE, SEEK_CUR);
+                       ret = para_fseek(infile, l - FRAME_HEADER_SIZE, SEEK_CUR);
+                       if (ret < 0)
+                               return ret;
                }
                if (k == MIN_CONSEC_GOOD_FRAMES) {
-                       fseek(infile, valid_start, SEEK_SET);
+                       ret = para_fseek(infile, valid_start, SEEK_SET);
+                       if (ret < 0)
+                               return ret;
                        memcpy(&(mp3.header), &h2, sizeof(struct mp3header));
                        return first_len;
                }
@@ -286,6 +291,7 @@ static int mp3_seek_next_header(void)
 static int mp3_get_id3(void)
 {
        char fbuf[4];
+       int ret;
 
        mp3.id3_isvalid = 0;
        mp3.id3.title[0] = '\0';
@@ -293,8 +299,9 @@ static int mp3_get_id3(void)
        mp3.id3.album[0] = '\0';
        mp3.id3.comment[0] = '\0';
        mp3.id3.year[0] = '\0';
-       if (fseek(infile, -128, SEEK_END))
-               return -E_FSEEK;
+       ret = para_fseek(infile, -128, SEEK_END);
+       if (ret < 0 )
+               return ret;
        if (para_fread(fbuf, 1, 3, infile) < 0)
                return -E_FREAD;
        fbuf[3] = '\0';
@@ -302,8 +309,9 @@ static int mp3_get_id3(void)
                PARA_INFO_LOG("%s", "no id3 tag\n");
                return 0;
        }
-       if (fseek(infile, -125, SEEK_END) < 0)
-               return -E_FSEEK;
+       ret = para_fseek(infile, -125, SEEK_END);
+       if (ret < 0)
+               return ret;
        if (para_fread(mp3.id3.title, 1, 30, infile) != 30)
                return -E_FREAD;
        mp3.id3.title[30] = '\0';
@@ -330,7 +338,7 @@ static int mp3_get_id3(void)
 
 static int find_valid_start(void)
 {
-       int frame_len;
+       int ret, frame_len;
 
        if (!infile)
                return -E_MP3_NO_FILE;
@@ -341,9 +349,11 @@ static int find_valid_start(void)
                frame_len = mp3_seek_next_header();
                if (frame_len <= 0)
                        return frame_len;
-       } else
-               if (fseek(infile, -FRAME_HEADER_SIZE, SEEK_CUR) < 0)
-                       return -E_FSEEK;
+       } else {
+               ret = para_fseek(infile, -FRAME_HEADER_SIZE, SEEK_CUR);
+               if (ret < 0)
+                       return ret;
+       }
        if (frame_len <= 1)
                return -E_FRAME_LENGTH;
        return frame_len;
@@ -370,8 +380,8 @@ static int mp3_read_info(void)
                int freq, br, fl;
                struct timeval tmp, cct; /* current chunk time */
                if (len > 0) {
-                       ret = -E_FSEEK;
-                       if (fseek(infile, len, SEEK_CUR) < 0)
+                       ret = para_fseek(infile, len, SEEK_CUR);
+                       if (ret < 0)
                                goto err_out;
                }
                len = find_valid_start();
@@ -417,8 +427,8 @@ static int mp3_read_info(void)
        ret = -E_MP3_INFO;
        if (!num_chunks || !freq_avg || !br_avg)
                goto err_out;
-       ret = -E_FSEEK;
-       if (fseek(infile, 0, SEEK_END) < 0)
+       ret= para_fseek(infile, 0, SEEK_END);
+       if (ret < 0)
                goto err_out;
        chunk_table[num_chunks] = ftell(infile);
        mp3.br_average = br_avg;
diff --git a/vss.c b/vss.c
index f1dbfb9..9aeff44 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -501,33 +501,38 @@ again:
        return ret;
 }
 
-static char *vss_read_chunk(long unsigned current_chunk, ssize_t *len)
+/**
+ * read a chunk of data from the current audio file
+ *
+ * \param current_chunk the chunk number to read
+ *
+ * \return The length of the chunk on success, zero on end of file, negative on
+ * errors.  Note: If the current chunk is of length zero, but the end of the
+ * file is not yet reached, this function returns -E_EMPTY_CHUNK.
+ * */
+ssize_t vss_read_chunk(void)
 {
-       int ret;
+       ssize_t len;
        size_t pos;
-
-       *len = 0;
-       if (current_chunk >= mmd->chunks_total)
-               return NULL;
-       *len = chunk_table[current_chunk + 1] - chunk_table[current_chunk];
-       if (!*len) /* nothing to send for this run */
-               return inbuf;
-       pos = chunk_table[current_chunk];
-       if (inbuf_size < *len) {
-               PARA_INFO_LOG("increasing inbuf for chunk #%lu/%lu to %zd bytes\n",
-                       current_chunk, mmd->chunks_total, *len);
-               inbuf = para_realloc(inbuf, *len);
-               inbuf_size = *len;
+       int ret;
+       long unsigned cc = mmd->current_chunk;
+
+       if (cc >= mmd->chunks_total) /* eof */
+               return 0;
+       len = chunk_table[cc + 1] - chunk_table[cc];
+       if (!len) /* nothing to send for this run */
+               return -E_EMPTY_CHUNK;
+       pos = chunk_table[cc];
+       if (inbuf_size < len) {
+               PARA_INFO_LOG("increasing inbuf for chunk #%lu/%lu to %zu bytes\n",
+                       cc, mmd->chunks_total, len);
+               inbuf = para_realloc(inbuf, len);
+               inbuf_size = len;
        }
-//     PARA_DEBUG_LOG("reading chunk #%lu@%zd (%zd bytes)\n", current_chunk,
-//             pos, *len);
-       ret = fseek(audio_file, pos, SEEK_SET);
+       ret = para_fseek(audio_file, pos, SEEK_SET);
        if (ret < 0)
-               return NULL;
-       ret = para_fread(inbuf, *len, 1, audio_file);
-       if (ret != *len)
-               return NULL;
-       return inbuf;
+               return ret;
+       return para_fread(inbuf, len, 1, audio_file);
 }
 
 /**
@@ -546,7 +551,6 @@ void vss_send_chunk(void)
 {
        int i;
        struct audio_format_handler *af;
-       char *buf;
        ssize_t ret;
        struct timeval now, due;
 
@@ -562,16 +566,23 @@ void vss_send_chunk(void)
        if (chk_barrier("data send", &now, &data_send_barrier,
                        &due, 1) < 0)
                return;
-       buf = vss_read_chunk(mmd->current_chunk, &ret);
+       ret= vss_read_chunk();
        mmd->new_vss_status_flags &= ~VSS_REPOS;
-       if (!buf) {
-               if (ret < 0)
+       if (!ret || (ret < 0 && ret != -E_EMPTY_CHUNK)) {
+               if (ret < 0) {
                        mmd->new_vss_status_flags = VSS_NEXT;
-               else
+                       PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+               } else
                        mmd->new_vss_status_flags |= VSS_NEXT;
                vss_eof(af);
                return;
        }
+       /*
+        * We call the send function also in case of empty chunks as they
+        * might have still some data queued which can be sent in this case.
+        */
+       if (ret < 0)
+               ret = 0;
        if (!mmd->chunks_sent) {
                struct timeval tmp;
                gettimeofday(&mmd->stream_start, NULL);
@@ -580,7 +591,7 @@ void vss_send_chunk(void)
                mmd->events++;
        }
        for (i = 0; senders[i].name; i++)
-               senders[i].send(mmd->current_chunk, mmd->chunks_sent, buf, ret);
+               senders[i].send(mmd->current_chunk, mmd->chunks_sent, inbuf, ret);
        mmd->new_vss_status_flags |= VSS_PLAYING;
        mmd->chunks_sent++;
        mmd->current_chunk++;