Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 55 additions & 19 deletions src/lz4stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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;
Expand Down
23 changes: 22 additions & 1 deletion src/lz4stream.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
#ifndef LZ4_STREAM_H_INCLUDED_
#define LZ4_STREAM_H_INCLUDED_

typedef struct lz4stream_t lz4stream;
#include <stdbool.h>

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);

Expand All @@ -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 */
Expand Down