summaryrefslogtreecommitdiffstats
path: root/programs/lz4io.c
diff options
context:
space:
mode:
authorYann Collet <cyan@fb.com>2022-07-15 14:11:26 (GMT)
committerYann Collet <cyan@fb.com>2022-07-15 17:30:53 (GMT)
commit6784e78e006329ba67eb799a1cb94dd7267a9241 (patch)
tree96330ac7e1f25829df98330cab8cc57eca44f35f /programs/lz4io.c
parent0c620ce212d92d009f47293ea5e0b676c3380fbb (diff)
downloadlz4-6784e78e006329ba67eb799a1cb94dd7267a9241.zip
lz4-6784e78e006329ba67eb799a1cb94dd7267a9241.tar.gz
lz4-6784e78e006329ba67eb799a1cb94dd7267a9241.tar.bz2
support skippable frames within pipe
fix #977 fseek() doesn't work for pipe, switch to "read and forget" mode in such case.
Diffstat (limited to 'programs/lz4io.c')
-rw-r--r--programs/lz4io.c25
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