rewritten FIO_decompressGzFile

This commit is contained in:
Przemyslaw Skibinski 2016-12-02 15:01:31 +01:00
parent b0f2ef2119
commit c5eebca128

View File

@ -652,106 +652,48 @@ static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_
#ifdef ZSTD_GZDECOMPRESS #ifdef ZSTD_GZDECOMPRESS
typedef struct gzipContext_s { static size_t FIO_decompressGzFile(dRess_t ress, size_t headBufSize, const char* srcFileName, FILE* srcFile)
int err;
char *msg;
z_stream strm;
} *gzipContext;
static gzipContext gzip_create(void)
{
gzipContext gzip;
gzip = malloc(sizeof(struct gzipContext_s));
if (gzip == NULL)
return NULL;
gzip->strm.zalloc = Z_NULL;
gzip->strm.zfree = Z_NULL;
gzip->strm.opaque = Z_NULL;
gzip->strm.next_in = 0;
gzip->strm.avail_in = Z_NULL;
if (inflateInit2(&(gzip->strm), 15 + 16) != Z_OK) {
free(gzip);
return NULL;
}
gzip->err = 0;
gzip->msg = "";
return gzip;
}
static int gzip_free(gzipContext gzip)
{
if (gzip == NULL) return Z_STREAM_ERROR;
inflateEnd(&(gzip->strm));
free(gzip);
return Z_OK;
}
static int gzip_decompress(gzipContext gzip, FILE* file, dRess_t ress, size_t headBufSize)
{ {
int ret; int ret;
unsigned readBytes;
unsigned char in[1]; unsigned char in[1];
unsigned char* headBuf = (unsigned char*)ress.srcBuffer; unsigned char* headBuf = (unsigned char*)ress.srcBuffer;
z_stream *strm; size_t decompBytes, outFileSize = 0;
z_stream strm;
if (gzip == NULL || gzip->err) strm.zalloc = Z_NULL;
return 0; strm.zfree = Z_NULL;
strm = &(gzip->strm); strm.opaque = Z_NULL;
strm->next_out = ress.dstBuffer; strm.next_in = 0;
strm->avail_out = ress.dstBufferSize; strm.avail_in = Z_NULL;
if (inflateInit2(&strm, 15 + 16) != Z_OK) return 0;
do { strm.next_out = ress.dstBuffer;
strm.avail_out = ress.dstBufferSize;
for ( ; ; ) {
if (headBufSize) { if (headBufSize) {
headBufSize--; headBufSize--;
in[0] = *headBuf++; in[0] = *headBuf++;
} else { } else {
readBytes = fread(in, 1, 1, file); if (fread(in, 1, 1, srcFile) == 0) break;
if (readBytes == 0)
break;
} }
strm->next_in = in; strm.next_in = in;
strm->avail_in = 1; strm.avail_in = 1;
ret = inflate(strm, Z_NO_FLUSH); ret = inflate(&strm, Z_NO_FLUSH);
if (ret == Z_DATA_ERROR) { if (ret == Z_STREAM_END) break;
gzip->err = Z_DATA_ERROR; if (ret != Z_OK) { DISPLAY("zstd: %s: inflate error %d \n", srcFileName, ret); return 0; }
gzip->msg = strm->msg;
return 0;
}
if (ret == Z_STREAM_END)
inflateReset(strm);
} while (strm->avail_out);
return ress.dstBufferSize - strm->avail_out; decompBytes = ress.dstBufferSize - strm.avail_out;
if (decompBytes) {
if (fwrite(ress.dstBuffer, 1, decompBytes, ress.dstFile) != (size_t)decompBytes) EXM_THROW(31, "Write error : cannot write to output file");
outFileSize += decompBytes;
strm.next_out = ress.dstBuffer;
strm.avail_out = ress.dstBufferSize;
}
} }
inflateEnd(&strm);
static unsigned long long FIO_decompressGzFile(dRess_t ress, size_t headBufSize, const char* srcFileName, FILE* srcFile) return outFileSize;
{
unsigned long long filesize = 0;
int readBytes;
gzipContext gzipCtx = gzip_create();
if (gzipCtx == NULL) { DISPLAY("zstd: %s: gzip_create error \n", srcFileName); return 0; }
for ( ; ; ) {
readBytes = gzip_decompress(gzipCtx, srcFile, ress, headBufSize);
printf("headBufSize=%d readBytes=%d dstBufferSize=%d\n", (int)headBufSize, (int)readBytes, (int)ress.dstBufferSize);
if (readBytes < 0) EXM_THROW(30, "zstd: %s: gzip_decompress error: %s \n", srcFileName, gzipCtx->msg);
if (readBytes == 0) break;
if (fwrite(ress.dstBuffer, 1, readBytes, ress.dstFile) != (size_t)readBytes) EXM_THROW(31, "Write error : cannot write to output file");
filesize += readBytes;
}
if (gzip_free(gzipCtx) != Z_OK) { DISPLAY("zstd: %s: gzip_free error \n", srcFileName); return 0; }
return filesize;
} }
#endif #endif
@ -767,9 +709,6 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName)
FILE* const dstFile = ress.dstFile; FILE* const dstFile = ress.dstFile;
FILE* srcFile; FILE* srcFile;
unsigned readSomething = 0; unsigned readSomething = 0;
size_t const suffixSize = strlen(GZ_EXTENSION);
size_t const sfnSize = strlen(srcFileName);
const char* const suffixPtr = srcFileName + sfnSize - suffixSize;
if (UTIL_isDirectory(srcFileName)) { if (UTIL_isDirectory(srcFileName)) {
DISPLAYLEVEL(1, "zstd: %s is a directory -- ignored \n", srcFileName); DISPLAYLEVEL(1, "zstd: %s is a directory -- ignored \n", srcFileName);
@ -779,7 +718,6 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName)
srcFile = FIO_openSrcFile(srcFileName); srcFile = FIO_openSrcFile(srcFileName);
if (srcFile==0) return 1; if (srcFile==0) return 1;
if (sfnSize <= suffixSize || strcmp(suffixPtr, GZ_EXTENSION) != 0) {
/* for each frame */ /* for each frame */
for ( ; ; ) { for ( ; ; ) {
/* check magic number -> version */ /* check magic number -> version */
@ -793,9 +731,15 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName)
readSomething = 1; /* there is at least >= 4 bytes in srcFile */ readSomething = 1; /* there is at least >= 4 bytes in srcFile */
if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */
if (buf[0] == 31 && buf[1] == 139) { /* gz header */ if (buf[0] == 31 && buf[1] == 139) { /* gz header */
unsigned long long result = FIO_decompressGzFile(ress, toRead, srcFileName, srcFile); #ifdef ZSTD_GZDECOMPRESS
size_t const result = FIO_decompressGzFile(ress, toRead, srcFileName, srcFile);
printf("result=%d\n", (int)result);
if (result == 0) return 1; if (result == 0) return 1;
filesize += result; filesize += result;
#else
DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName);
return 1;
#endif
} else { } else {
if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { if (!ZSTD_isFrame(ress.srcBuffer, toRead)) {
if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */
@ -809,18 +753,9 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName)
} } } }
filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize);
} }
printf("filesize=%d\n", (int)filesize);
} }
} }
} else {
#ifndef ZSTD_GZDECOMPRESS
DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName);
return 1;
#else
unsigned long long result = FIO_decompressGzFile(ress, 0, srcFileName, srcFile);
if (result == 0) return 1;
filesize += result;
#endif
}
/* Final Status */ /* Final Status */
DISPLAYLEVEL(2, "\r%79s\r", ""); DISPLAYLEVEL(2, "\r%79s\r", "");