diff --git a/Makefile b/Makefile index e2ffe57..2642ee9 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ CC = gcc COMPILE = $(CC) $(CFLAGS) -c -o LD = $(CC) $(LDFLAGS) -o -PROGS = write read list +PROGS = write read list pread COMMON = common.o endian.o cpu.o all: $(PROGS) diff --git a/common.c b/common.c index f9ce387..c728a1a 100644 --- a/common.c +++ b/common.c @@ -40,6 +40,7 @@ void *decode_block_start(off_t block_seek) { if (fseeko(gInFile, block_seek, SEEK_SET) == -1) die("Error seeking to block"); + // Some memory in which to keep the discovered filters safe block_wrapper_t *bw = malloc(sizeof(block_wrapper_t)); bw->block = (lzma_block){ .check = gCheck, .filters = bw->filters, .version = 0 }; @@ -94,7 +95,7 @@ void free_file_index(void) { gFileIndex = gLastFile = NULL; } -bool read_file_index(void) { +lzma_vli find_file_index(void **bdatap) { if (!gIndex) decode_index(); @@ -112,10 +113,29 @@ bool read_file_index(void) { // Check if this is really an index read_file_index_data(); - if (xle64dec(gFileIndexBuf + gFIBPos) != PIXZ_INDEX_MAGIC) { + lzma_vli ret = iter.block.compressed_file_offset; + if (xle64dec(gFileIndexBuf + gFIBPos) != PIXZ_INDEX_MAGIC) + ret = 0; + + if (bdatap && ret) { + *bdatap = bdata; + } else { + // Just looking, don't keep things around + if (bdatap) + *bdatap = NULL; + free(bdata); + free(gFileIndexBuf); gLastFile = gFileIndex = NULL; - return false; + lzma_end(&gStream); } + return ret; +} + +bool read_file_index(void) { + void *bdata; + find_file_index(&bdata); + if (!bdata) + return false; while (true) { char *name = read_file_index_name(); diff --git a/pixz.h b/pixz.h index 3dbfc06..1530d5c 100644 --- a/pixz.h +++ b/pixz.h @@ -52,6 +52,7 @@ extern file_index_t *gFileIndex, *gLastFile; void decode_index(void); +lzma_vli find_file_index(void **bdatap); bool read_file_index(void); void dump_file_index(FILE *out); void free_file_index(void); diff --git a/pread.c b/pread.c new file mode 100644 index 0000000..4d1a14d --- /dev/null +++ b/pread.c @@ -0,0 +1,40 @@ +#include "pixz.h" + +/* TODO + * - parallel extraction + * - restrict to certain files + * - verify file-index matches archive contents + */ + +static FILE *gOutFile = NULL; + +static size_t largest_block_size(); + +int main(int argc, char **argv) { + // TODO: Arguments? + gInFile = stdin; + gOutFile = stdout; + + // Find largest block size + size_t blocksize = largest_block_size(); + printf("block size: %zu\n", blocksize); + + return 0; +} + +static size_t largest_block_size() { + // exclude the index block + lzma_vli index_offset = find_file_index(NULL); + + lzma_index_iter iter; + lzma_index_iter_init(&iter, gIndex); + + size_t largest = 0; + while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)) { + if (index_offset && iter.block.compressed_file_offset == index_offset) + continue; + if (iter.block.uncompressed_size > largest) + largest = iter.block.uncompressed_size; + } + return largest; +}