]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - aft.c
server: Store max chunk size in database.
[paraslash.git] / aft.c
diff --git a/aft.c b/aft.c
index 77891342313e17295d5b60ea836fd9b187705ae9..4e2e1f8dbe2af69df7f5927a11687a236975c5a3 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -335,8 +335,8 @@ enum afhi_offsets {
        CHUNKS_TOTAL_OFFSET = 20,
        /** The length of the audio file header (4 bytes). */
        HEADER_LEN_OFFSET = 24,
-       /** Was: The start of the audio file header (4 bytes). */
-       AFHI_UNUSED2_OFFSET = 28,
+       /** Size of the largest chunk in bytes. (4 bytes). */
+       AFHI_MAX_CHUNK_SIZE_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). */
@@ -376,7 +376,7 @@ static void save_afhi(struct afh_info *afhi, char *buf)
        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 + AFHI_UNUSED2_OFFSET, 0);
+       write_u32(buf + AFHI_MAX_CHUNK_SIZE_OFFSET, afhi->max_chunk_size);
        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;
@@ -398,6 +398,7 @@ static void load_afhi(const char *buf, struct afh_info *afhi)
        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->max_chunk_size = read_u32(buf + AFHI_MAX_CHUNK_SIZE_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;
@@ -415,35 +416,21 @@ static unsigned sizeof_chunk_table(struct afh_info *afhi)
        return 4 * (afhi->chunks_total + 1);
 }
 
-static uint32_t save_chunk_table(struct afh_info *afhi, char *buf)
+static void save_chunk_table(struct afh_info *afhi, char *buf)
 {
-       int i;
-       uint32_t max = 0, old = 0;
+       uint32_t n;
 
-       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;
+       for (n = 0; n <= afhi->chunks_total; n++)
+               write_u32(buf + 4 * n, afhi->chunk_table[n]);
 }
 
-static void load_chunk_table(struct afh_info *afhi, char *buf)
+static void load_chunk_table(struct afh_info *afhi, const struct osl_object *ct)
 {
        int i;
 
        afhi->chunk_table = para_malloc(sizeof_chunk_table(afhi));
-       for (i = 0; i <= afhi->chunks_total; i++)
-               afhi->chunk_table[i] = read_u32(buf + 4 * i);
+       for (i = 0; i <= afhi->chunks_total && i * 4 + 3 < ct->size; i++)
+               afhi->chunk_table[i] = read_u32(ct->data + 4 * i);
 }
 
 /**
@@ -638,7 +625,13 @@ static int save_afd(struct audio_file_data *afd)
                goto err;
        buf = shm_afd;
        buf += sizeof(*afd);
-       afd->max_chunk_size = save_chunk_table(&afd->afhi, buf);
+       save_chunk_table(&afd->afhi, buf);
+       if (afd->afhi.max_chunk_size == 0) { /* v0.5.x on-disk afhi */
+               set_max_chunk_size(&afd->afhi);
+               PARA_NOTICE_LOG("max chunk size unset, re-add required\n");
+       } else
+               PARA_INFO_LOG("using max chunk size from afhi\n");
+       afd->max_chunk_size = afd->afhi.max_chunk_size;
        *(struct audio_file_data *)shm_afd = *afd;
        shm_detach(shm_afd);
        return shmid;
@@ -663,14 +656,22 @@ int load_afd(int shmid, struct audio_file_data *afd)
 {
        void *shm_afd;
        int ret;
+       struct osl_object obj;
 
        ret = shm_attach(shmid, ATTACH_RO, &shm_afd);
        if (ret < 0)
                return ret;
+       ret = shm_size(shmid, &obj.size);
+       if (ret < 0)
+               goto detach;
        *afd = *(struct audio_file_data *)shm_afd;
-       load_chunk_table(&afd->afhi, shm_afd + sizeof(*afd));
+       obj.data = shm_afd + sizeof(*afd);
+       obj.size -= sizeof(*afd);
+       load_chunk_table(&afd->afhi, &obj);
+       ret = 1;
+detach:
        shm_detach(shm_afd);
-       return 1;
+       return ret;
 }
 
 static int get_local_time(uint64_t *seconds, char *buf, size_t size,
@@ -820,7 +821,11 @@ static int print_chunk_table(struct ls_data *d, struct para_buffer *b)
                (long unsigned) d->afhi.chunk_tv.tv_usec
        );
        buf = chunk_table_obj.data;
-       for (i = 0; i <= d->afhi.chunks_total; i++)
+       for (
+               i = 0;
+               i <= d->afhi.chunks_total && 4 * i + 3 < chunk_table_obj.size;
+               i++
+       )
                para_printf(b, "%u ", (unsigned) read_u32(buf + 4 * i));
        para_printf(b, "\n");
        ret = 1;
@@ -935,6 +940,8 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts,
        WRITE_STATUS_ITEM(b, SI_CHUNK_TIME, "%lu\n", tv2ms(&afhi->chunk_tv));
        WRITE_STATUS_ITEM(b, SI_NUM_CHUNKS, "%" PRIu32 "\n",
                afhi->chunks_total);
+       WRITE_STATUS_ITEM(b, SI_MAX_CHUNK_SIZE, "%" PRIu32 "\n",
+               afhi->max_chunk_size);
        WRITE_STATUS_ITEM(b, SI_TECHINFO, "%s\n", afhi->techinfo);
        WRITE_STATUS_ITEM(b, SI_ARTIST, "%s\n", afhi->tags.artist);
        WRITE_STATUS_ITEM(b, SI_TITLE, "%s\n", afhi->tags.title);
@@ -1072,7 +1079,7 @@ again:
        save_afsi(&new_afsi, &afsi_obj); /* in-place update */
 
        afd->audio_format_id = d->afsi.audio_format_id;
-       load_chunk_table(&afd->afhi, chunk_table_obj.data);
+       load_chunk_table(&afd->afhi, &chunk_table_obj);
        aced.aft_row = current_aft_row;
        aced.old_afsi = &d->afsi;
        /*
@@ -2044,6 +2051,22 @@ static int com_touch_callback(struct afs_callback_arg *aca)
                .data = aca,
                .action = touch_audio_file
        };
+       if (cto->image_id >= 0) {
+               ret = img_get_name_by_id(cto->image_id, NULL);
+               if (ret < 0) {
+                       para_printf(&aca->pbout, "invalid image ID: %d\n",
+                               cto->image_id);
+                       return ret;
+               }
+       }
+       if (cto->lyrics_id >= 0) {
+               ret = lyr_get_name_by_id(cto->lyrics_id, NULL);
+               if (ret < 0) {
+                       para_printf(&aca->pbout, "invalid lyrics ID: %d\n",
+                               cto->lyrics_id);
+                       return ret;
+               }
+       }
        if (cto->flags & TOUCH_FLAG_FNM_PATHNAME)
                pmd.fnmatch_flags |= FNM_PATHNAME;
        ret = for_each_matching_row(&pmd);