More infrastructure to read from temporary buffers on stdin decompression.

This commit is contained in:
Con Kolivas 2011-03-14 21:19:57 +11:00
parent 36e09f206e
commit c832e80085
4 changed files with 40 additions and 21 deletions

View file

@ -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);
} else {
fd_in = open(infilecopy, O_RDONLY);
if (unlikely(fd_in == -1)) {

View file

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

View file

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

View file

@ -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