gzstd: decompresses .gz files

This commit is contained in:
Przemyslaw Skibinski 2016-11-30 15:05:54 +01:00
parent 0e14675df2
commit abfb51f5f2
2 changed files with 57 additions and 33 deletions

View File

@ -82,7 +82,7 @@ zstd : $(ZSTDDECOMP_O) $(ZSTD_FILES) $(ZSTDLEGACY_FILES) $(ZDICT_FILES) \
ifneq (,$(filter Windows%,$(OS))) ifneq (,$(filter Windows%,$(OS)))
windres\generate_res.bat windres\generate_res.bat
endif endif
$(CC) $(FLAGS) $^ $(RES_FILE) -o $@$(EXT) $(CC) $(FLAGS) $^ $(RES_FILE) -o $@$(EXT) $(LDFLAGS)
zstd32 : CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) zstd32 : CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT)
@ -124,6 +124,9 @@ zstd-decompress: clean_decomp_o
zstd-compress: $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) zstdcli.c fileio.c zstd-compress: $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) zstdcli.c fileio.c
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS $^ -o $@$(EXT) $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS $^ -o $@$(EXT)
gzstd: clean_decomp_o
CFLAGS+=-DZSTD_GZDECOMPRESS LDFLAGS+=-lz $(MAKE) zstd
generate_res: generate_res:
windres\generate_res.bat windres\generate_res.bat

View File

@ -34,6 +34,9 @@
#include "fileio.h" #include "fileio.h"
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_magicNumber, ZSTD_frameHeaderSize_max */ #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_magicNumber, ZSTD_frameHeaderSize_max */
#include "zstd.h" #include "zstd.h"
#ifdef ZSTD_GZDECOMPRESS
#include "zlib.h"
#endif
/*-************************************* /*-*************************************
@ -657,56 +660,74 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName)
{ {
unsigned long long filesize = 0; unsigned long long filesize = 0;
FILE* const dstFile = ress.dstFile; FILE* const dstFile = ress.dstFile;
FILE* srcFile;
unsigned readSomething = 0; unsigned readSomething = 0;
size_t const suffixSize = strlen(GZ_EXTENSION); size_t const suffixSize = strlen(GZ_EXTENSION);
size_t const sfnSize = strlen(srcFileName); size_t const sfnSize = strlen(srcFileName);
const char* const suffixPtr = srcFileName + sfnSize - suffixSize; const char* const suffixPtr = srcFileName + sfnSize - suffixSize;
if (sfnSize > suffixSize && strcmp(suffixPtr, GZ_EXTENSION) == 0) {
DISPLAYLEVEL(1, "zstd: %s: gz file cannot be uncompressed -- ignored \n", srcFileName);
return 1;
}
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);
return 1; return 1;
} }
srcFile = FIO_openSrcFile(srcFileName); if (sfnSize <= suffixSize || strcmp(suffixPtr, GZ_EXTENSION) != 0) {
if (srcFile==0) return 1; FILE* srcFile = FIO_openSrcFile(srcFileName);
if (srcFile==0) return 1;
/* for each frame */ /* for each frame */
for ( ; ; ) { for ( ; ; ) {
/* check magic number -> version */ /* check magic number -> version */
size_t const toRead = 4; size_t const toRead = 4;
size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile); size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile);
if (sizeCheck==0) { if (sizeCheck==0) {
if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */
break; /* no more input */ break; /* no more input */
}
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 (!ZSTD_isFrame(ress.srcBuffer, toRead)) {
if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */
unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize);
if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */
return result;
} else {
DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName);
fclose(srcFile);
return 1;
} }
filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize);
} }
readSomething = 1; /* there is at least >= 4 bytes in srcFile */ /* Close file */
if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ if (fclose(srcFile)) EXM_THROW(33, "zstd: %s close error", srcFileName); /* error should never happen */
if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { } else {
if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ #ifndef ZSTD_GZDECOMPRESS
unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); DISPLAYLEVEL(1, "zstd: %s: gz file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName);
if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ return 1;
return result; #else
} else { int readBytes;
DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); gzFile gzSrcFile = gzopen(srcFileName, "rb");
fclose(srcFile); if (gzSrcFile == NULL) { DISPLAY("zstd: %s: gzopen error \n", srcFileName); return 1; }
return 1;
} } do {
filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); readBytes = gzread(gzSrcFile, ress.dstBuffer, ress.dstBufferSize);
if (readBytes < 0) { DISPLAY("zstd: %s: gzread error \n", srcFileName); return 1; }
if (readBytes > 0) {
size_t const sizeCheck = fwrite(ress.dstBuffer, 1, readBytes, dstFile);
if (sizeCheck != (size_t)readBytes) EXM_THROW(34, "Write error : cannot write to output file");
}
filesize += readBytes;
} while ((size_t)readBytes == ress.dstBufferSize);
if (gzclose(gzSrcFile) != Z_OK) { DISPLAY("zstd: %s: gzclose error \n", srcFileName); return 1; }
#endif
} }
/* Final Status */ /* Final Status */
DISPLAYLEVEL(2, "\r%79s\r", ""); DISPLAYLEVEL(2, "\r%79s\r", "");
DISPLAYLEVEL(2, "%-20s: %llu bytes \n", srcFileName, filesize); DISPLAYLEVEL(2, "%-20s: %llu bytes \n", srcFileName, filesize);
/* Close */ /* Remove source file */
if (fclose(srcFile)) EXM_THROW(33, "zstd: %s close error", srcFileName); /* error should never happen */ if (g_removeSrcFile) { if (remove(srcFileName)) EXM_THROW(35, "zstd: %s: %s", srcFileName, strerror(errno)); };
if (g_removeSrcFile) { if (remove(srcFileName)) EXM_THROW(34, "zstd: %s: %s", srcFileName, strerror(errno)); };
return 0; return 0;
} }