diff options
Diffstat (limited to 'contrib/libarchive/libarchive/test/read_open_memory.c')
-rw-r--r-- | contrib/libarchive/libarchive/test/read_open_memory.c | 98 |
1 files changed, 75 insertions, 23 deletions
diff --git a/contrib/libarchive/libarchive/test/read_open_memory.c b/contrib/libarchive/libarchive/test/read_open_memory.c index db0de8555a62..0d88df5f4f83 100644 --- a/contrib/libarchive/libarchive/test/read_open_memory.c +++ b/contrib/libarchive/libarchive/test/read_open_memory.c @@ -39,7 +39,8 @@ __FBSDID("$FreeBSD$"); */ struct read_memory_data { - unsigned char *buffer; + unsigned char *start; + unsigned char *p; unsigned char *end; size_t read_size; size_t copy_buff_size; @@ -49,7 +50,8 @@ struct read_memory_data { static int memory_read_close(struct archive *, void *); static int memory_read_open(struct archive *, void *); -static off_t memory_read_skip(struct archive *, void *, off_t request); +static int64_t memory_read_seek(struct archive *, void *, int64_t request, int whence); +static int64_t memory_read_skip(struct archive *, void *, int64_t request); static ssize_t memory_read(struct archive *, void *, const void **buff); static int read_open_memory_internal(struct archive *a, void *buff, size_t size, size_t read_size, int fullapi); @@ -58,7 +60,7 @@ static int read_open_memory_internal(struct archive *a, void *buff, int read_open_memory(struct archive *a, void *buff, size_t size, size_t read_size) { - return read_open_memory_internal(a, buff, size, read_size, 1); + return read_open_memory_internal(a, buff, size, read_size, 2); } /* @@ -68,12 +70,21 @@ read_open_memory(struct archive *a, void *buff, size_t size, size_t read_size) int read_open_memory2(struct archive *a, void *buff, size_t size, size_t read_size) { - return read_open_memory_internal(a, buff, size, read_size, 0); + return read_open_memory_internal(a, buff, size, read_size, 1); +} + +/* + * Include a seek callback as well. + */ +int +read_open_memory_seek(struct archive *a, void *buff, size_t size, size_t read_size) +{ + return read_open_memory_internal(a, buff, size, read_size, 3); } static int read_open_memory_internal(struct archive *a, void *buff, - size_t size, size_t read_size, int fullapi) + size_t size, size_t read_size, int level) { struct read_memory_data *mine; @@ -83,19 +94,26 @@ read_open_memory_internal(struct archive *a, void *buff, return (ARCHIVE_FATAL); } memset(mine, 0, sizeof(*mine)); - mine->buffer = (unsigned char *)buff; - mine->end = mine->buffer + size; + mine->start = mine->p = (unsigned char *)buff; + mine->end = mine->start + size; mine->read_size = read_size; mine->copy_buff_offset = 32; mine->copy_buff_size = read_size + mine->copy_buff_offset * 2; mine->copy_buff = malloc(mine->copy_buff_size); memset(mine->copy_buff, 0xA5, mine->copy_buff_size); - if (fullapi) - return (archive_read_open2(a, mine, memory_read_open, - memory_read, memory_read_skip, memory_read_close)); - else - return (archive_read_open2(a, mine, NULL, - memory_read, NULL, memory_read_close)); + + switch (level) { + case 3: + archive_read_set_seek_callback(a, memory_read_seek); + case 2: + archive_read_set_open_callback(a, memory_read_open); + archive_read_set_skip_callback(a, memory_read_skip); + case 1: + archive_read_set_read_callback(a, memory_read); + archive_read_set_close_callback(a, memory_read_close); + archive_read_set_callback_data(a, mine); + } + return archive_read_open1(a); } /* @@ -119,41 +137,75 @@ static ssize_t memory_read(struct archive *a, void *client_data, const void **buff) { struct read_memory_data *mine = (struct read_memory_data *)client_data; - size_t size; + ssize_t size; (void)a; /* UNUSED */ - size = mine->end - mine->buffer; - if (size > mine->read_size) + size = mine->end - mine->p; + if (size < 0) { + buff = NULL; + return 0; + } + if ((size_t)size > mine->read_size) size = mine->read_size; else memset(mine->copy_buff, 0xA5, mine->copy_buff_size); - memcpy(mine->copy_buff + mine->copy_buff_offset, mine->buffer, size); + memcpy(mine->copy_buff + mine->copy_buff_offset, mine->p, size); *buff = mine->copy_buff + mine->copy_buff_offset; - mine->buffer += size; + mine->p += size; return ((ssize_t)size); } /* * How mean can a skip() routine be? Let's try to find out. */ -static off_t -memory_read_skip(struct archive *a, void *client_data, off_t skip) +static int64_t +memory_read_skip(struct archive *a, void *client_data, int64_t skip) { struct read_memory_data *mine = (struct read_memory_data *)client_data; (void)a; /* UNUSED */ /* We can't skip by more than is available. */ - if ((off_t)skip > (off_t)(mine->end - mine->buffer)) - skip = mine->end - mine->buffer; + if ((off_t)skip > (off_t)(mine->end - mine->p)) + skip = mine->end - mine->p; /* Always do small skips by prime amounts. */ if (skip > 71) skip = 71; - mine->buffer += skip; + mine->p += skip; return (skip); } /* + */ +static int64_t +memory_read_seek(struct archive *a, void *client_data, int64_t offset, int whence) +{ + struct read_memory_data *mine = (struct read_memory_data *)client_data; + + (void)a; /* UNUSED */ + switch (whence) { + case SEEK_SET: + mine->p = mine->start + offset; + break; + case SEEK_END: + mine->p = mine->end + offset; + break; + case SEEK_CUR: + mine->p += offset; + break; + } + if (mine->p < mine->start) { + mine->p = mine->start; + return ARCHIVE_FAILED; + } + if (mine->p > mine->end) { + mine->p = mine->end; + return ARCHIVE_FAILED; + } + return (mine->p - mine->start); +} + +/* * Close is just cleaning up our one small bit of data. */ static int |