diff options
Diffstat (limited to 'programs/lz4io.c')
-rw-r--r-- | programs/lz4io.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/programs/lz4io.c b/programs/lz4io.c index 36736c2..5644775 100644 --- a/programs/lz4io.c +++ b/programs/lz4io.c @@ -1152,6 +1152,23 @@ LZ4IO_passThrough(FILE* finput, FILE* foutput, return total; } +/* when fseek() doesn't work (pipe scenario), + * read and forget from input. +**/ +#define SKIP_BUFF_SIZE (16 KB) +#define MIN(a,b) ( ((a)<(b)) ? (a) : (b) ) +static int skipStream(FILE* f, unsigned offset) +{ + char buf[SKIP_BUFF_SIZE]; + while (offset > 0) { + size_t const tr = MIN(offset, sizeof(buf)); + size_t const r = fread(buf, 1, tr, f); + if (r != tr) return 1; /* error reading f */ + offset -= (unsigned)tr; + } + assert(offset == 0); + return 0; +} /** Safely handle cases when (unsigned)offset > LONG_MAX */ static int fseek_u32(FILE *fp, unsigned offset, int where) @@ -1163,13 +1180,15 @@ static int fseek_u32(FILE *fp, unsigned offset, int where) while (offset > 0) { unsigned s = offset; if (s > stepMax) s = stepMax; - errorNb = UTIL_fseek(fp, (long) s, SEEK_CUR); - if (errorNb != 0) break; - offset -= s; + errorNb = UTIL_fseek(fp, (long)s, SEEK_CUR); + if (errorNb==0) { offset -= s; continue; } + errorNb = skipStream(fp, offset); + offset = 0; } return errorNb; } + #define ENDOFSTREAM ((unsigned long long)-1) #define DECODING_ERROR ((unsigned long long)-2) static unsigned long long |