]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Improve the listing performance of CAB reader; Do not decode compressed data
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Thu, 22 Mar 2012 13:57:16 +0000 (22:57 +0900)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Thu, 22 Mar 2012 13:57:16 +0000 (22:57 +0900)
until archive_read_data* is invoked.

libarchive/archive_read_support_format_cab.c

index 0f49a47b26a1c052fff92923adfae448becb4b9d..a2e66468013ed2fea0db62e51805f30efd6d6fef 100644 (file)
@@ -292,6 +292,8 @@ struct cab {
        char                     end_of_archive;
        char                     end_of_entry;
        char                     end_of_entry_cleanup;
+       char                     read_data_invoked;
+       int64_t                  bytes_skipped;
 
        unsigned char           *uncompressed_buffer;
        size_t                   uncompressed_buffer_size;
@@ -1026,6 +1028,19 @@ archive_read_format_cab_read_data(struct archive_read *a,
        default:
                break;
        }
+       if (cab->read_data_invoked == 0) {
+               if (cab->bytes_skipped) {
+                       if (cab->entry_cfdata == NULL) {
+                               int r = cab_next_cfdata(a);
+                               if (r < 0)
+                                       return (r);
+                       }
+                       if (cab_consume_cfdata(a, cab->bytes_skipped) < 0)
+                               return (ARCHIVE_FATAL);
+                       cab->bytes_skipped = 0;
+               }
+               cab->read_data_invoked = 1;
+       }
        if (cab->entry_unconsumed) {
                /* Consume as much as the compressor actually used. */
                r = (int)cab_consume_cfdata(a, cab->entry_unconsumed);
@@ -1952,6 +1967,14 @@ archive_read_format_cab_read_data_skip(struct archive_read *a)
        if (cab->end_of_archive)
                return (ARCHIVE_EOF);
 
+       if (!cab->read_data_invoked) {
+               cab->bytes_skipped += cab->entry_bytes_remaining;
+               cab->entry_bytes_remaining = 0;
+               /* This entry is finished and done. */
+               cab->end_of_entry_cleanup = cab->end_of_entry = 1;
+               return (ARCHIVE_OK);
+       }
+
        if (cab->entry_unconsumed) {
                /* Consume as much as the compressor actually used. */
                r = (int)cab_consume_cfdata(a, cab->entry_unconsumed);