diff --git a/src/lz4stream.c b/src/lz4stream.c index 425857f..3cb5de3 100644 --- a/src/lz4stream.c +++ b/src/lz4stream.c @@ -23,25 +23,6 @@ #define LZ4S_B0_VERSION_MASK 0xC0 #define LZ4S_B1_RESERVED_MASK 0x8f -typedef struct lz4stream_t -{ - int fd; // compressed file - void *compressed_buffer; // buffer for compressed data - int compressed_buffer_size; - void *uncompressed_buffer; - int decoded_bytes; - int mode; - char *error; - - bool block_checksum_flag; - bool stream_checksum_flag; - int block_size; - int eof; - void *offset; - void *mapped_file; - size_t file_size; -} lz4stream; - static void * read_stream_headers(lz4stream * lz) { uint8_t header[3] = {0, 0, 0}; @@ -257,6 +238,61 @@ int lz4stream_read_block(lz4stream * lz, void * tail) return lz->decoded_bytes; }; +int lz4stream_read(lz4stream *lz, void *buffer, unsigned int len) { + + if(lz->eof && lz->tail == NULL) { + return 0; + } + + void *tail = lz->tail; + + int total_read = 0; + void *start = buffer; + + if (tail != NULL) { + + int bytes_left_in_buffer = lz->decoded_bytes - (tail - lz->uncompressed_buffer); + + if (bytes_left_in_buffer >= len) { + memcpy(buffer, tail, len); + lz->tail += len; + return len; + } else if (bytes_left_in_buffer >= 0) { + memcpy(buffer, tail, bytes_left_in_buffer); + tail = NULL; + total_read += bytes_left_in_buffer; + start += bytes_left_in_buffer; + } + + } + + int bytes_read; + + while ((bytes_read = lz4stream_read_block(lz, tail)) > 0) { + + tail = NULL; + void *uncompressed_buffer = lz4stream_get_buffer(lz); + + if (total_read + bytes_read >= len) { + int num_to_use = (bytes_read - (total_read + bytes_read - len)); + memcpy(start, uncompressed_buffer, num_to_use); + total_read = len; + tail = uncompressed_buffer + num_to_use; + break; + } else { + memcpy(start, uncompressed_buffer, bytes_read); + total_read += bytes_read; + start += bytes_read; + } + + } + + lz->tail = tail; + + return total_read; + +} + int lz4stream_get_decoded_bytes(lz4stream * lz) { return lz->decoded_bytes; diff --git a/src/lz4stream.h b/src/lz4stream.h index a290c26..671ef61 100644 --- a/src/lz4stream.h +++ b/src/lz4stream.h @@ -1,7 +1,27 @@ #ifndef LZ4_STREAM_H_INCLUDED_ #define LZ4_STREAM_H_INCLUDED_ -typedef struct lz4stream_t lz4stream; +#include + +typedef struct lz4stream_t +{ + int fd; // compressed file + void *compressed_buffer; // buffer for compressed data + int compressed_buffer_size; + void *uncompressed_buffer; + int decoded_bytes; + int mode; + char *error; + + bool block_checksum_flag; + bool stream_checksum_flag; + int block_size; + int eof; + void *offset; + void *mapped_file; + size_t file_size; + void *tail; +} lz4stream; lz4stream * lz4stream_open_read(const char * filename); @@ -10,6 +30,7 @@ lz4stream * lz4stream_open_read(const char * filename); lz4stream * lz4stream_fdopen_read(int fd); int lz4stream_close(lz4stream * lz); int lz4stream_read_block(lz4stream * lz, void * tail); +int lz4stream_read(lz4stream *file, void *buffer, unsigned int len); char * lz4stream_strerror(lz4stream * lz); /* access decoded data */