From c832e8008550176d3ae861962e16483adef164c2 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Mon, 14 Mar 2011 21:19:57 +1100 Subject: [PATCH] More infrastructure to read from temporary buffers on stdin decompression. --- lrzip.c | 11 ++++------- runzip.c | 4 ++-- stream.c | 44 +++++++++++++++++++++++++++++++++----------- stream.h | 2 +- 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/lrzip.c b/lrzip.c index 7792c1f..9fd7980 100644 --- a/lrzip.c +++ b/lrzip.c @@ -387,6 +387,8 @@ static void read_tmpinmagic(rzip_control *control) magic[i] = (char)tmpchar; } get_magicver05(control, magic); + control->in_relofs = 24; + if (control->major_version == 0 && control->minor_version > 5) { for (i = 24; i < MAGIC_LEN; i++) { tmpchar = getchar(); @@ -394,6 +396,7 @@ static void read_tmpinmagic(rzip_control *control) failure("Reached end of file on STDIN prematurely on v06 magic read\n"); magic[i] = (char)tmpchar; } + control->in_relofs = MAGIC_LEN; } } @@ -517,13 +520,7 @@ void decompress_file(rzip_control *control) fd_in = open_tmpinfile(control); read_tmpinmagic(control); expected_size = control->st_size; - /* Version 0.6+ files we can tell how much to read for each - * chunk in advance and decide if we can do it using a - * temporary buffer instead of a temporary file */ - if (control->major_version == 0 && control->minor_version > 5) - open_tmpinbuf(control); - else - read_tmpinfile(control, fd_in); + open_tmpinbuf(control); } else { fd_in = open(infilecopy, O_RDONLY); if (unlikely(fd_in == -1)) { diff --git a/runzip.c b/runzip.c index 491cfd9..d54794f 100644 --- a/runzip.c +++ b/runzip.c @@ -253,7 +253,7 @@ static i64 runzip_chunk(rzip_control *control, int fd_in, int fd_out, int fd_his chunk_bytes = 8; else { /* Read in the stored chunk byte width from the file */ - if (unlikely(read(fd_in, &chunk_bytes, 1) != 1)) + if (unlikely(read_1g(control, fd_in, &chunk_bytes, 1) != 1)) fatal("Failed to read chunk_bytes size in runzip_chunk\n"); } if (!tally && expected_size) @@ -299,7 +299,7 @@ static i64 runzip_chunk(rzip_control *control, int fd_in, int fd_out, int fd_his print_maxverbose("Checksum for block: 0x%08x\n", cksum); } - if (unlikely(close_stream_in(ss))) + if (unlikely(close_stream_in(control, ss))) fatal("Failed to close stream!\n"); return total; diff --git a/stream.c b/stream.c index 954b7b7..a7eb574 100644 --- a/stream.c +++ b/stream.c @@ -688,11 +688,11 @@ static void read_fdin(struct rzip_control *control, i64 len) for (i = 0; i < len; i++) { tmpchar = getchar(); if (unlikely(tmpchar == EOF)) - failure("Reached end of file on STDIN prematurely on read_fdin\n"); + failure("Reached end of file on STDIN prematurely on read_fdin, asked for %lld got %lld\n", + len, i); control->tmp_inbuf[control->in_ofs + i] = (char)tmpchar; } - control->in_ofs += len; - control->in_len = control->in_ofs; + control->in_len = control->in_ofs + len; } static i64 seekto_fdin(rzip_control *control, i64 pos) @@ -842,6 +842,18 @@ static int read_seekto(rzip_control *control, struct stream_info *sinfo, i64 pos { i64 spos = pos + sinfo->initial_pos; + if (TMP_INBUF) { + spos -= control->in_relofs; + if (spos > control->in_len) + read_fdin(control, spos - control->in_len); + control->in_ofs = spos; + if (unlikely(spos < 0)) { + print_err("Trying to seek to %lld outside tmp inbuf in read_seekto\n", spos); + return -1; + } + return 0; + } + return fd_seekto(control, sinfo, spos, pos); } @@ -857,6 +869,18 @@ static i64 get_seek(rzip_control *control, int fd) return ret; } +static i64 get_readseek(rzip_control *control, int fd) +{ + i64 ret; + + if (TMP_INBUF) + return control->in_relofs + control->in_ofs; + ret = lseek(fd, 0, SEEK_CUR); + if (unlikely(ret == -1)) + fatal("Failed to lseek in get_seek\n"); + return ret; +} + void prepare_streamout_threads(rzip_control *control) { int i; @@ -1034,7 +1058,7 @@ void *open_stream_in(rzip_control *control, int f, int n) print_maxverbose("Chunk size: %lld\n", sinfo->size); control->st_size += sinfo->size; } - sinfo->initial_pos = lseek(f, 0, SEEK_CUR); + sinfo->initial_pos = get_readseek(control, f); for (i = 0; i < n; i++) { uchar c; @@ -1056,7 +1080,7 @@ again: goto failed; if (unlikely(read_u32(control, f, &v232))) goto failed; - if ((read_u32(control, f, &last_head32))) + if (unlikely(read_u32(control, f, &last_head32))) goto failed; v1 = v132; @@ -1072,7 +1096,6 @@ again: goto failed; header_length = 25; } - if (unlikely(c == CTYPE_NONE && v1 == 0 && v2 == 0 && sinfo->s[i].last_head == 0 && i == 0)) { print_err("Enabling stream close workaround\n"); sinfo->initial_pos += header_length; @@ -1080,7 +1103,6 @@ again: } sinfo->total_read += header_length; - if (unlikely(c != CTYPE_NONE)) { print_err("Unexpected initial tag %d in streams\n", c); goto failed; @@ -1517,14 +1539,14 @@ int close_stream_out(rzip_control *control, void *ss) } /* close down an input stream */ -int close_stream_in(void *ss) +int close_stream_in(rzip_control *control, void *ss) { struct stream_info *sinfo = ss; int i; - if (unlikely(lseek(sinfo->fd, sinfo->initial_pos + sinfo->total_read, - SEEK_SET) != sinfo->initial_pos + sinfo->total_read)) - return -1; + if (unlikely(read_seekto(control, sinfo, sinfo->initial_pos + sinfo->total_read))) + return -1; + for (i = 0; i < sinfo->num_streams; i++) free(sinfo->s[i].buf); diff --git a/stream.h b/stream.h index 3ba8c55..d56b735 100644 --- a/stream.h +++ b/stream.h @@ -36,7 +36,7 @@ void flush_buffer(rzip_control *control, struct stream_info *sinfo, int stream); int write_stream(rzip_control *control, void *ss, int streamno, uchar *p, i64 len); i64 read_stream(rzip_control *control, void *ss, int streamno, uchar *p, i64 len); int close_stream_out(rzip_control *control, void *ss); -int close_stream_in(void *ss); +int close_stream_in(rzip_control *control, void *ss); const i64 one_g; #endif