fade: Quiesce two gcc warnings.
[paraslash.git] / aft.c
diff --git a/aft.c b/aft.c
index a112abe766af318a876bef5fdb2c62c480e4fd63..266188b5b370a3e7e3e8aaa092ca093aca7c6c04 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2009 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2007-2011 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -21,7 +21,6 @@
 #include "afh.h"
 #include "afs.h"
 #include "net.h"
-#include "vss.h"
 #include "fd.h"
 #include "ipc.h"
 #include "portable_io.h"
@@ -238,7 +237,7 @@ enum audio_file_table_columns {
  *
  * \sa osl_compare_func, uint32_compare().
  */
-int aft_hash_compare(const struct osl_object *obj1, const struct osl_object *obj2)
+static int aft_hash_compare(const struct osl_object *obj1, const struct osl_object *obj2)
 {
        return hash_compare((HASH_TYPE *)obj1->data, (HASH_TYPE *)obj2->data);
 }
@@ -345,16 +344,16 @@ enum afhi_offsets {
        AFHI_BITRATE_OFFSET = 4,
        /** Position of the frequency. */
        AFHI_FREQUENCY_OFFSET = 8,
-       /** Location of the audio file header. */
-       AFHI_HEADER_OFFSET_OFFSET = 12,
+       /** Was: Location of the audio file header. */
+       AFHI_UNUSED1_OFFSET = 12,
        /* Length of the audio file header. Zero means: No header. */
        AFHI_HEADER_LEN_OFFSET = 16,
        /** The total number of chunks (4 bytes). */
        CHUNKS_TOTAL_OFFSET = 20,
        /** The length of the audio file header (4 bytes). */
        HEADER_LEN_OFFSET = 24,
-       /** The start of the audio file header (4 bytes). */
-       HEADER_OFFSET_OFFSET = 28,
+       /** Was: The start of the audio file header (4 bytes). */
+       AFHI_UNUSED2_OFFSET = 28,
        /** The seconds part of the chunk time (4 bytes). */
        CHUNK_TV_TV_SEC_OFFSET = 32,
        /** The microseconds part of the chunk time (4 bytes). */
@@ -389,12 +388,12 @@ static void save_afhi(struct afh_info *afhi, char *buf)
        write_u32(buf + AFHI_SECONDS_TOTAL_OFFSET, afhi->seconds_total);
        write_u32(buf + AFHI_BITRATE_OFFSET, afhi->bitrate);
        write_u32(buf + AFHI_FREQUENCY_OFFSET, afhi->frequency);
-       write_u32(buf + AFHI_HEADER_OFFSET_OFFSET, afhi->header_offset);
+       write_u32(buf + AFHI_UNUSED1_OFFSET, 0);
        write_u32(buf + AFHI_HEADER_LEN_OFFSET, afhi->header_len);
        write_u8(buf + AFHI_CHANNELS_OFFSET, afhi->channels);
        write_u32(buf + CHUNKS_TOTAL_OFFSET, afhi->chunks_total);
        write_u32(buf + HEADER_LEN_OFFSET, afhi->header_len);
-       write_u32(buf + HEADER_OFFSET_OFFSET, afhi->header_offset);
+       write_u32(buf + AFHI_UNUSED2_OFFSET, 0);
        write_u32(buf + CHUNK_TV_TV_SEC_OFFSET, afhi->chunk_tv.tv_sec);
        write_u32(buf + CHUNK_TV_TV_USEC_OFFSET, afhi->chunk_tv.tv_usec);
        p = buf + AFHI_INFO_STRING_OFFSET;
@@ -412,12 +411,10 @@ static void load_afhi(const char *buf, struct afh_info *afhi)
        afhi->seconds_total = read_u32(buf + AFHI_SECONDS_TOTAL_OFFSET);
        afhi->bitrate = read_u32(buf + AFHI_BITRATE_OFFSET);
        afhi->frequency = read_u32(buf + AFHI_FREQUENCY_OFFSET);
-       afhi->header_offset = read_u32(buf + AFHI_HEADER_OFFSET_OFFSET);
        afhi->header_len = read_u32(buf + AFHI_HEADER_LEN_OFFSET);
        afhi->channels = read_u8(buf + AFHI_CHANNELS_OFFSET);
        afhi->chunks_total = read_u32(buf + CHUNKS_TOTAL_OFFSET);
        afhi->header_len = read_u32(buf + HEADER_LEN_OFFSET);
-       afhi->header_offset = read_u32(buf + HEADER_OFFSET_OFFSET);
        afhi->chunk_tv.tv_sec = read_u32(buf + CHUNK_TV_TV_SEC_OFFSET);
        afhi->chunk_tv.tv_usec = read_u32(buf + CHUNK_TV_TV_USEC_OFFSET);
        afhi->techinfo = (char *)buf + AFHI_INFO_STRING_OFFSET;
@@ -435,12 +432,26 @@ static unsigned sizeof_chunk_table(struct afh_info *afhi)
        return 4 * (afhi->chunks_total + 1);
 }
 
-static void save_chunk_table(struct afh_info *afhi, char *buf)
+static uint32_t save_chunk_table(struct afh_info *afhi, char *buf)
 {
        int i;
-
-       for (i = 0; i <= afhi->chunks_total; i++)
-               write_u32(buf + 4 * i, afhi->chunk_table[i]);
+       uint32_t max = 0, old = 0;
+
+       for (i = 0; i <= afhi->chunks_total; i++) {
+               uint32_t val = afhi->chunk_table[i];
+               write_u32(buf + 4 * i, val);
+               /*
+                * If the first chunk is the header, do not consider it for the
+                * calculation of the largest chunk size.
+                */
+               if (i == 0 || (i == 1 && afhi->header_len > 0)) {
+                       old = val;
+                       continue;
+               }
+               max = PARA_MAX(max, val - old);
+               old = val;
+       }
+       return max;
 }
 
 static void load_chunk_table(struct afh_info *afhi, char *buf)
@@ -475,7 +486,7 @@ int aft_get_row_of_path(const char *path, struct osl_row **row)
  *
  * \return Standard.
  */
-int aft_get_row_of_hash(HASH_TYPE *hash, struct osl_row **row)
+static int aft_get_row_of_hash(HASH_TYPE *hash, struct osl_row **row)
 {
        const struct osl_object obj = {.data = hash, .size = HASH_SIZE};
        return osl(osl_get_row(audio_file_table, AFTCOL_HASH, &obj, row));
@@ -503,7 +514,7 @@ int get_afsi_object_of_row(const struct osl_row *row, struct osl_object *obj)
  *
  * \return Positive on success, negative on errors.
  */
-int get_afsi_object_of_path(const char *path, struct osl_object *obj)
+static int get_afsi_object_of_path(const char *path, struct osl_object *obj)
 {
        struct osl_row *row;
        int ret = aft_get_row_of_path(path, &row);
@@ -641,10 +652,10 @@ static int save_afd(struct audio_file_data *afd)
        ret = shm_attach(shmid, ATTACH_RW, &shm_afd);
        if (ret < 0)
                goto err;
-       *(struct audio_file_data *)shm_afd = *afd;
        buf = shm_afd;
        buf += sizeof(*afd);
-       save_chunk_table(&afd->afhi, buf);
+       afd->max_chunk_size = save_chunk_table(&afd->afhi, buf);
+       *(struct audio_file_data *)shm_afd = *afd;
        shm_detach(shm_afd);
        return shmid;
 err:
@@ -652,6 +663,18 @@ err:
        return ret;
 }
 
+/**
+ * Extract a afd stored in a shared memory area.
+ *
+ * Attach the shared memory area given by \a shmid, load the audio file data
+ * stored therein and detach the area afterwards.  Called by vss, after
+ * receiving a positive response to the request for the next audio file.
+ +
+ * \param shmid The identifier of the shared memory area containing the afd.
+ * \param afd Result pointer.
+ *
+ * \return Standard.
+ */
 int load_afd(int shmid, struct audio_file_data *afd)
 {
        void *shm_afd;
@@ -1070,6 +1093,7 @@ int open_and_update_audio_file(struct osl_row *aft_row, long score,
        ret = get_audio_file_path_of_row(aft_row, &path);
        if (ret < 0)
                return ret;
+       PARA_NOTICE_LOG("%s\n", path);
        ret = get_afsi_object_of_row(aft_row, &afsi_obj);
        if (ret < 0)
                return ret;
@@ -1100,6 +1124,7 @@ int open_and_update_audio_file(struct osl_row *aft_row, long score,
        new_afsi.last_played = time(NULL);
        save_afsi(&new_afsi, &afsi_obj); /* in-place update */
 
+       afd->audio_format_id = old_afsi.audio_format_id;
        load_chunk_table(&afd->afhi, chunk_table_obj.data);
        ret = make_status_items(afd, &old_afsi, path, score, file_hash);
        if (ret < 0)
@@ -2435,7 +2460,7 @@ int com_cpsi(struct rc4_context *rc4c, int argc,  char * const * const argv)
        return ret;
 }
 
-void afs_stat_callback(int fd, const struct osl_object *query)
+static void afs_stat_callback(int fd, const struct osl_object *query)
 {
        int *parser_friendly = query->data;
        char *buf = *parser_friendly?
@@ -2446,6 +2471,18 @@ void afs_stat_callback(int fd, const struct osl_object *query)
        pass_buffer_as_shm(buf, strlen(buf), &fd);
 }
 
+/**
+ * Get the current afs status items from the afs process and send it using RC4.
+ *
+ * \param rc4c The rc4 context for data encryption.
+ * \param parser_friendly Whether parser-friendly output format should be used.
+ *
+ * As the contents of the afs status items change in time and the command
+ * handler only has a COW version created at fork time, it can not send
+ * up-to-date afs status items directly. Therefore the usual callback mechanism
+ * is used to pass the status items from the afs process to the command handler
+ * via a shared memory area and a pipe.
+ */
 int send_afs_status(struct rc4_context *rc4c, int parser_friendly)
 {
        struct osl_object query = {.data = &parser_friendly,
@@ -2610,6 +2647,11 @@ static int aft_event_handler(enum afs_events event, struct para_buffer *pb,
        }
 }
 
+/**
+ * Initialize the audio file table.
+ *
+ * \param t Pointer to the structure to be initialized.
+ */
 void aft_init(struct afs_table *t)
 {
        t->open = aft_open;