|
|
} | } |
| |
/* | /* |
* Skip at most request bytes. Skipped data is marked as consumed. |
* Skip forward by exactly the requested bytes or else return |
|
* ARCHIVE_FATAL. Note that this differs from the contract for |
|
* read_ahead, which does not gaurantee a minimum count. |
*/ | */ |
static ssize_t | static ssize_t |
archive_decompressor_none_skip(struct archive *a, size_t request) | archive_decompressor_none_skip(struct archive *a, size_t request) |
|
|
if (request == 0) | if (request == 0) |
return (total_bytes_skipped); | return (total_bytes_skipped); |
/* | /* |
* If no client_skipper is provided, just read the old way. It is very |
* If a client_skipper was provided, try that first. |
* likely that after skipping, the request has not yet been fully |
|
* satisfied (and is still > 0). In that case, read as well. |
|
*/ | */ |
if (a->client_skipper != NULL) { | if (a->client_skipper != NULL) { |
bytes_skipped = (a->client_skipper)(a, a->client_data, | bytes_skipped = (a->client_skipper)(a, a->client_data, |
|
|
a->raw_position += bytes_skipped; | a->raw_position += bytes_skipped; |
state->client_avail = state->client_total = 0; | state->client_avail = state->client_total = 0; |
} | } |
|
/* |
|
* Note that client_skipper will usually not satisfy the |
|
* full request (due to low-level blocking concerns), |
|
* so even if client_skipper is provided, we may still |
|
* have to use ordinary reads to finish out the request. |
|
*/ |
while (request > 0) { | while (request > 0) { |
const void* dummy_buffer; | const void* dummy_buffer; |
ssize_t bytes_read; | ssize_t bytes_read; |
|
|
&dummy_buffer, request); | &dummy_buffer, request); |
if (bytes_read < 0) | if (bytes_read < 0) |
return (bytes_read); | return (bytes_read); |
|
if (bytes_read == 0) { |
|
/* We hit EOF before we satisfied the skip request. */ |
|
archive_set_error(a, ARCHIVE_ERRNO_MISC, |
|
"Truncated input file (need to skip %d bytes)", (int)request); |
|
return (ARCHIVE_FATAL); |
|
} |
assert(bytes_read >= 0); /* precondition for cast below */ | assert(bytes_read >= 0); /* precondition for cast below */ |
min = minimum((size_t)bytes_read, request); | min = minimum((size_t)bytes_read, request); |
bytes_read = archive_decompressor_none_read_consume(a, min); | bytes_read = archive_decompressor_none_read_consume(a, min); |