Start factoring out index decoding

stream
Dave Vasilevsky 12 years ago
parent aa79e87956
commit 28e0515d75

@ -229,39 +229,112 @@ static void read_file_index_data(void) {
}
}
bool decode_index(void) {
if (fseek(gInFile, -LZMA_STREAM_HEADER_SIZE, SEEK_END) == -1)
return false; // not seekable
#define BWCHUNK 512
typedef struct {
uint8_t buf[BWCHUNK];
off_t pos;
size_t size;
} bw;
static uint32_t *bw_read(bw *b) {
size_t sz = sizeof(uint32_t);
if (b->size < sz) {
if (b->pos < sz)
return NULL; // EOF
b->size = (b->pos > BWCHUNK) ? BWCHUNK : b->pos;
b->pos -= b->size;
if (fseeko(gInFile, b->pos, SEEK_SET) == -1)
return NULL;
if (fread(b->buf, b->size, 1, gInFile) != 1)
return NULL;
}
b->size -= sz;
return &((uint32_t*)b->buf)[b->size / sz];
}
static off_t stream_padding(bw *b, off_t pos) {
b->pos = pos;
b->size = 0;
for (off_t pad = 0; true; ++pad) {
uint32_t *i = bw_read(b);
if (!i)
die("Error reading stream padding");
if (*i != 0) {
b->size += sizeof(uint32_t);
return pad;
}
}
}
static void stream_footer(bw *b, lzma_stream_flags *flags) {
uint8_t ftr[LZMA_STREAM_HEADER_SIZE];
for (int i = sizeof(ftr) / sizeof(uint32_t) - 1; i >= 0; --i) {
uint32_t *p = bw_read(b);
if (!p)
die("Error reading stream footer");
*((uint32_t*)ftr + i) = *p;
}
uint8_t hdrbuf[LZMA_STREAM_HEADER_SIZE];
if (fread(hdrbuf, LZMA_STREAM_HEADER_SIZE, 1, gInFile) != 1)
die("Error reading stream footer");
lzma_stream_flags flags;
if (lzma_stream_footer_decode(&flags, hdrbuf) != LZMA_OK)
if (lzma_stream_footer_decode(flags, ftr) != LZMA_OK)
die("Error decoding stream footer");
gCheck = flags.check;
size_t index_seek = -LZMA_STREAM_HEADER_SIZE - flags.backward_size;
if (fseek(gInFile, index_seek, SEEK_CUR) == -1)
gCheck = flags->check; // FIXME: multiple streams
}
static lzma_index *next_index(off_t *pos) {
bw b;
off_t pad = stream_padding(&b, *pos);
off_t eos = *pos - pad;
lzma_stream_flags flags;
stream_footer(&b, &flags);
*pos = eos - LZMA_STREAM_HEADER_SIZE - flags.backward_size;
if (fseeko(gInFile, *pos, SEEK_SET) == -1)
die("Error seeking to index");
if (lzma_index_decoder(&gStream, &gIndex, MEMLIMIT) != LZMA_OK)
lzma_stream strm = LZMA_STREAM_INIT;
lzma_index *index;
if (lzma_index_decoder(&strm, &index, MEMLIMIT) != LZMA_OK)
die("Error creating index decoder");
uint8_t ibuf[CHUNKSIZE];
gStream.avail_in = 0;
strm.avail_in = 0;
lzma_ret err = LZMA_OK;
while (err != LZMA_STREAM_END) {
if (gStream.avail_in == 0) {
gStream.avail_in = fread(ibuf, 1, CHUNKSIZE, gInFile);
if (strm.avail_in == 0) {
strm.avail_in = fread(ibuf, 1, CHUNKSIZE, gInFile);
if (ferror(gInFile))
die("Error reading index");
gStream.next_in = ibuf;
strm.next_in = ibuf;
}
err = lzma_code(&gStream, LZMA_RUN);
err = lzma_code(&strm, LZMA_RUN);
if (err != LZMA_OK && err != LZMA_STREAM_END)
die("Error decoding index");
}
*pos = eos - lzma_index_stream_size(index);
if (fseeko(gInFile, *pos, SEEK_SET) == -1)
die("Error seeking to beginning of stream");
if (lzma_index_stream_flags(index, &flags) != LZMA_OK)
die("Error setting stream flags");
if (lzma_index_stream_padding(index, pad) != LZMA_OK)
die("Error setting stream padding");
return index;
}
bool decode_index(void) {
if (fseeko(gInFile, 0, SEEK_END) == -1)
return false; // not seekable
off_t pos = ftello(gInFile);
gIndex = next_index(&pos);
return true;
}

Loading…
Cancel
Save