bufseek: Changed specification and improved range checking.
authorNicolas Pennequin <nicolas.pennequin@free.fr>
Sun, 5 Aug 2007 18:17:29 +0000 (5 20:17 +0200)
committerNicolas Pennequin <nicolas.pennequin@free.fr>
Sun, 5 Aug 2007 18:17:29 +0000 (5 20:17 +0200)
It makes more sense to seek within the file than within the available data,
(that would be overly complicated for the caller anyway).
Seeking to a point before the available data should now trigger a rebuffer
(required for the case of rewinding to the start of an audio track), but I
haven't tested this yet.

testplugin.c

index 109b10e..5348c50 100644 (file)
@@ -544,23 +544,50 @@ int bufclose(int handle_id)
     return 0;
 }
 
-/* Set reading index in handle (relatively to the start of the handle data).
-   Return 0 for success and < 0 for failure */
-int bufseek(int handle_id, size_t offset)
+/* Set reading index in handle (relatively to the start of the file).
+   Access before the available data will trigger a rebuffer.
+   TODO: Test this
+   TODO: Maybe force an immediate rebuffer by calling buffer_handle() ?
+   Return 0 for success and < 0 for failure:
+     -1 if the handle wasn't found
+     -2 if there is no data available at the new position
+        (the reading index is still moved)
+     -3 if the new requested position was beyond the end of the file
+*/
+int bufseek(int handle_id, size_t newpos)
 {
+    int ret = 0;
     struct memory_handle *h = find_handle(handle_id);
     if (!h)
         return -1;
 
-    if (offset > h->available)
-        return -2;
+    if (newpos > h->filesize) {
+        /* access beyond the end of the file */
+        return -3;
+    }
 
-    h->ridx = RINGBUF_ADD(h->data, offset);
-    return 0;
+    else if (newpos < h->offset) {
+        /* access before what we currently have. A rebuffer is needed. */
+        h->offset = newpos;
+        h->available = 0;
+        h->filerem = h->filesize - newpos;
+        /* having changed filerem should be enough to trigger the rebuffer. */
+        h->widx = h->data;
+        ret = -2;
+    }
+
+    else if (newpos > h->offset + h->available) {
+        /* data isn't available yet. */
+        ret = -2;
+    }
+
+    h->ridx = RINGBUF_ADD(h->data, newpos);
+    return ret;
 }
 
 /* Advance the reading index in a handle (relatively to its current position).
-   Return 0 for success and < 0 for failure */
+   Return 0 for success and < 0 for failure
+   TODO: Add some rebuffering like in bufseek */
 int bufadvance(int handle_id, off_t offset)
 {
     struct memory_handle *h = find_handle(handle_id);