summaryrefslogtreecommitdiffstats
path: root/programs/lz4io.c
diff options
context:
space:
mode:
authorYann Collet <cyan@fb.com>2019-04-22 21:01:19 (GMT)
committerYann Collet <cyan@fb.com>2019-04-22 21:01:19 (GMT)
commit0d4c885abb793b3bdb7ad6c815671e5847b53e6e (patch)
tree037697915b9eeae5cc86e18fd4a153164da49bee /programs/lz4io.c
parentae5cea9112479df58d226f79ae34c07bc636a04d (diff)
downloadlz4-0d4c885abb793b3bdb7ad6c815671e5847b53e6e.zip
lz4-0d4c885abb793b3bdb7ad6c815671e5847b53e6e.tar.gz
lz4-0d4c885abb793b3bdb7ad6c815671e5847b53e6e.tar.bz2
refactored --list function
better handling of special conditions, better scoping of variables. Also : updated man page
Diffstat (limited to 'programs/lz4io.c')
-rw-r--r--programs/lz4io.c176
1 files changed, 97 insertions, 79 deletions
diff --git a/programs/lz4io.c b/programs/lz4io.c
index 1e6efe1..e3eed93 100644
--- a/programs/lz4io.c
+++ b/programs/lz4io.c
@@ -1275,87 +1275,105 @@ typedef struct {
LZ4F_frameInfo_t frameInfo;
const char* fileName;
unsigned long long fileSize;
-} LZ4F_compFileInfo_t;
-
-#define LZ4F_INIT_FILEINFO { LZ4F_INIT_FRAMEINFO, NULL, 0ULL }
-
-
-static int LZ4IO_getCompressedFileInfo(const char* input_filename, LZ4F_compFileInfo_t* cfinfo){
- const char *b,
- *e;
- char *t;
- stat_t statbuf;
- size_t readSize = LZ4F_HEADER_SIZE_MAX;
- LZ4F_errorCode_t errorCode;
- dRess_t ress;
- /* Open file */
- FILE* const finput = LZ4IO_openSrcFile(input_filename);
- if (finput==NULL) return 1;
-
- /* Get file size */
- if (!UTIL_getFileStat(input_filename, &statbuf)){
- EXM_THROW(60, "Can't stat file : %s", input_filename);
- }
-
- cfinfo->fileSize = (unsigned long long)statbuf.st_size;
-
- /* Get basename without extension */
- b = strrchr(input_filename, '/');
- if (!b){
- b = strrchr(input_filename, '\\');
- }
- if (b && b != input_filename){
- b++;
- } else{
- b=input_filename;
- }
- e = strrchr(b, '.');
-
- /* Allocate Memory */
- t = (char*)malloc( (size_t)(e-b+1) * sizeof(char));
- ress.srcBuffer = malloc(LZ4IO_dBufferSize);
- if (!t || !ress.srcBuffer)
- EXM_THROW(21, "Allocation error : not enough memory");
- strncpy(t, b, (e-b));
- t[e-b] = '\0';
- cfinfo->fileName = t;
-
- /* init */
- errorCode = LZ4F_createDecompressionContext(&ress.dCtx, LZ4F_VERSION);
- if (LZ4F_isError(errorCode)) EXM_THROW(60, "Can't create LZ4F context : %s", LZ4F_getErrorName(errorCode));
-
- if (!fread(ress.srcBuffer, readSize, 1, finput)){
- EXM_THROW(30, "Error reading %s ", input_filename);
- }
- LZ4F_getFrameInfo(ress.dCtx, &cfinfo->frameInfo, ress.srcBuffer, &readSize);
-
- /* Close input/free resources */
- fclose(finput);
- free(ress.srcBuffer);
- return 0;
-}
+} LZ4IO_cFileInfo_t;
+
+#define LZ4IO_INIT_CFILEINFO { LZ4F_INIT_FRAMEINFO, NULL, 0ULL }
+
+
+/* This function is limited,
+ * it only works fine for a file consisting of a single valid frame.
+ * It will / may stop program execution if a single filename is wrong.
+ * It will not look at content beyond first frame header.
+ *
+ * Things to improve :
+ * - continue execution after an error, just report an error code, keep all memory clean
+ * - check the entire file for additional content after first frame
+ * + combine results from multiple frames, give total
+ * - Optional :
+ * + report nb of blocks, hence max. possible decompressed size (when not reported in header)
+ * + report block type (B4D, B7I, etc.)
+ */
+static int
+LZ4IO_getCompressedFileInfo(LZ4IO_cFileInfo_t* cfinfo, const char* input_filename)
+{
+ /* Get file size */
+ cfinfo->fileSize = UTIL_getFileSize(input_filename); /* returns 0 if cannot read information */
-int LZ4IO_displayCompressedFilesInfo(const char** inFileNames, const size_t ifnIdx){
- size_t idx;
- int op_result=0;
- double ratio;
- DISPLAY("%16s\t%-20s\t%-20s\t%-10s\t%s\n","BlockChecksumFlag","Compressed", "Uncompressed", "Ratio", "Filename");
- for(idx=0; idx<ifnIdx; idx++){
- /* Get file info */
- LZ4F_compFileInfo_t cfinfo = LZ4F_INIT_FILEINFO;
- op_result=LZ4IO_getCompressedFileInfo(inFileNames[idx], &cfinfo);
- if (op_result != 0){
- DISPLAYLEVEL(1, "Failed to get frame info for file %s\n", inFileNames[idx]);
- /* Don't bother trying to process any other file */
- break;
+ /* Get filename without path prefix */
+ { const char* b = strrchr(input_filename, '/');
+ if (!b) {
+ b = strrchr(input_filename, '\\');
+ }
+ if (b && b != input_filename) {
+ b++;
+ } else {
+ b = input_filename;
+ }
+ cfinfo->fileName = b;
}
- if(cfinfo.frameInfo.contentSize){
- ratio = (double)cfinfo.fileSize / cfinfo.frameInfo.contentSize;
- DISPLAY("%-16d\t%-20llu\t%-20llu\t%-8.4f\t%s\n",cfinfo.frameInfo.blockChecksumFlag,cfinfo.fileSize,cfinfo.frameInfo.contentSize, ratio, cfinfo.fileName);
+
+ /* Read file and extract header */
+ { size_t readSize = LZ4F_HEADER_SIZE_MAX;
+ void* buffer = malloc(readSize);
+ LZ4F_dctx* dctx;
+
+ if (!buffer) EXM_THROW(21, "Allocation error : not enough memory");
+ { LZ4F_errorCode_t const errorCode =
+ LZ4F_createDecompressionContext(&dctx, LZ4F_VERSION);
+ if (LZ4F_isError(errorCode))
+ EXM_THROW(60, "Can't create LZ4F context : %s",
+ LZ4F_getErrorName(errorCode));
+ }
+
+ { FILE* const finput = LZ4IO_openSrcFile(input_filename);
+ if (finput==NULL) return 1;
+ if (!fread(buffer, readSize, 1, finput)) {
+ EXM_THROW(30, "Error reading %s ", input_filename);
+ }
+ fclose(finput);
+ }
+
+ { LZ4F_errorCode_t const errorCode =
+ LZ4F_getFrameInfo(dctx, &cfinfo->frameInfo, buffer, &readSize);
+ if (LZ4F_isError(errorCode))
+ EXM_THROW(60, "Cannot interpret LZ4 frame : %s",
+ LZ4F_getErrorName(errorCode));
+ }
+
+ /* clean */
+ free(buffer);
+ LZ4F_freeDecompressionContext(dctx);
}
- else{
- DISPLAY("%-16d\t%-20llu\t%-20s\t%-10s\t%s\n",cfinfo.frameInfo.blockChecksumFlag,cfinfo.fileSize, "-", "-", cfinfo.fileName);
+
+ return 0;
+}
+
+int LZ4IO_displayCompressedFilesInfo(const char** inFileNames, const size_t ifnIdx)
+{
+ size_t idx;
+
+ DISPLAY("%16s\t%-20s\t%-20s\t%-10s\t%s\n",
+ "BlockChecksumFlag","Compressed", "Uncompressed", "Ratio", "Filename");
+
+ for (idx=0; idx<ifnIdx; idx++) {
+ /* Get file info */
+ LZ4IO_cFileInfo_t cfinfo = LZ4IO_INIT_CFILEINFO;
+ int const op_result = LZ4IO_getCompressedFileInfo(&cfinfo, inFileNames[idx]);
+ if (op_result != 0) {
+ DISPLAYLEVEL(1, "Failed to get frame info for file %s\n", inFileNames[idx]);
+ /* Don't bother processing any more file */
+ return 1;
+ }
+ if (cfinfo.frameInfo.contentSize) {
+ double const ratio = (double)cfinfo.fileSize / cfinfo.frameInfo.contentSize;
+ DISPLAY("%-16d\t%-20llu\t%-20llu\t%-8.4f\t%s\n",
+ cfinfo.frameInfo.blockChecksumFlag, cfinfo.fileSize,
+ cfinfo.frameInfo.contentSize, ratio, cfinfo.fileName);
+ } else {
+ DISPLAY("%-16d\t%-20llu\t%-20s\t%-10s\t%s\n",
+ cfinfo.frameInfo.blockChecksumFlag, cfinfo.fileSize,
+ "-", "-", cfinfo.fileName);
+ }
}
- }
- return op_result;
+ return 0;
}