]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Give formats/filters way to know data amount requested from archive_read_data().
authorAndres Mejia <amejia004@gmail.com>
Sat, 26 Jan 2013 03:01:56 +0000 (22:01 -0500)
committerAndres Mejia <amejia004@gmail.com>
Sat, 26 Jan 2013 03:01:56 +0000 (22:01 -0500)
libarchive/archive_read.c
libarchive/archive_read_private.h
libarchive/archive_read_support_format_rar.c

index c569a63fe35ef389358a5c88a9c08f9e2cccbca6..048c316c52d43b0fcaaf6927c1176d1479133fef 100644 (file)
@@ -660,6 +660,8 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
 
        a->read_data_output_offset = 0;
        a->read_data_remaining = 0;
+       a->read_data_is_posix_read = 0;
+       a->read_data_requested = 0;
        a->data_start_node = a->client.cursor;
        /* EOF always wins; otherwise return the worst error. */
        return (r2 < r1 || r2 == ARCHIVE_EOF) ? r2 : r1;
@@ -771,6 +773,8 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
        while (s > 0) {
                if (a->read_data_remaining == 0) {
                        read_buf = a->read_data_block;
+                       a->read_data_is_posix_read = 1;
+                       a->read_data_requested = s;
                        r = _archive_read_data_block(&a->archive, &read_buf,
                            &a->read_data_remaining, &a->read_data_offset);
                        a->read_data_block = read_buf;
@@ -824,6 +828,8 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
                        bytes_read += len;
                }
        }
+       a->read_data_is_posix_read = 0;
+       a->read_data_requested = 0;
        return (bytes_read);
 }
 
index 587c8a33eee419a19909230837a28479a7f82315..8a6c859a8a1431f974657409e99435afe0dfda47 100644 (file)
@@ -161,6 +161,14 @@ struct archive_read {
        int64_t           read_data_output_offset;
        size_t            read_data_remaining;
 
+       /*
+        * Used by formats/filters to determine the amount of data
+        * requested from a call to archive_read_data(). This is only
+        * useful when the format/filter has seek support.
+        */
+       char              read_data_is_posix_read;
+       size_t            read_data_requested;
+
        /* Callbacks to open/read/write/close client archive streams. */
        struct archive_read_client client;
 
index 1bd95a3956b9d3baf9279eacc8e327b88d01ee20..632908ea18dad833d8dc50d67b40c92c260ef62f 100644 (file)
@@ -2796,6 +2796,8 @@ rar_read_ahead(struct archive_read *a, size_t min, ssize_t *avail)
   int ret;
   if (avail)
   {
+    if (a->read_data_is_posix_read && *avail > (ssize_t)a->read_data_requested)
+      *avail = a->read_data_requested;
     if (*avail > rar->bytes_remaining)
       *avail = (ssize_t)rar->bytes_remaining;
     if (*avail < 0)