Updated : cmake/CMakeLists.txt, by Nobuhiro Iwamatsu
Updated : cmake/pack/CMakeLists.txt, by Dmitry Cherepanov lz4demo : CLI accept aggregated commands lz4demo : detect overwrite output lz4demo : new commands options (-hc, -y) git-svn-id: https://lz4.googlecode.com/svn/trunk@91 650e7d94-2a16-8b24-b05c-7c0b3f6821cd
This commit is contained in:
parent
633c51904e
commit
647baabcef
@ -83,6 +83,12 @@ if(BUILD_SHARED_LIBS)
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
||||
|
||||
install(FILES
|
||||
${SRC_DIR}/lz4.h
|
||||
${SRC_DIR}/lz4hc.h
|
||||
DESTINATION include)
|
||||
|
||||
endif(BUILD_SHARED_LIBS)
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 2.8)
|
||||
PROJECT(LZ4)
|
||||
|
||||
############################## CPACK
|
||||
set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../)
|
||||
set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../)
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LZ4 Packer")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR 0)
|
||||
set(CPACK_PACKAGE_VERSION_MINOR 0)
|
||||
|
@ -1,21 +0,0 @@
|
||||
|
||||
lz4demo and fuzzer is an open-source demo compression algorithm LZ4 programs
|
||||
Copyright (C) Yann Collet 2012
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
You can contact the author at :
|
||||
- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
|
||||
- LZ4 source repository : http://code.google.com/p/lz4/
|
3
fuzzer.c
3
fuzzer.c
@ -36,6 +36,7 @@
|
||||
#include <stdio.h> // fgets, sscanf
|
||||
#include <sys/timeb.h> // timeb
|
||||
#include "lz4.h"
|
||||
#include "lz4hc.h"
|
||||
|
||||
|
||||
//**************************************
|
||||
@ -110,7 +111,7 @@ int FUZ_SecurityTest()
|
||||
|
||||
free(input);
|
||||
free(output);
|
||||
printf(" Completed (r=%i)\n",r);
|
||||
printf(" Completed (return = %i < 0)\n",r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
1
lz4.c
1
lz4.c
@ -710,6 +710,7 @@ int LZ4_compress(const char* source,
|
||||
// are safe against "buffer overflow" attack type.
|
||||
// They will never write nor read outside of the provided output buffers.
|
||||
// LZ4_uncompress_unknownOutputSize() also insures that it will never read outside of the input buffer.
|
||||
// LZ4_uncompress() guarantees that it will never read before source, nor beyond source + LZ4_compressBound(osize)
|
||||
// A corrupted input will produce an error result, a negative int, indicating the position of the error within input stream.
|
||||
|
||||
int LZ4_uncompress(const char* source,
|
||||
|
2
lz4.h
2
lz4.h
@ -66,7 +66,7 @@ LZ4_compress() :
|
||||
|
||||
LZ4_uncompress() :
|
||||
osize : is the output size, therefore the original size
|
||||
return : the number of bytes read in the source buffer
|
||||
return : the number of bytes read in the source buffer (in other words, the compressed size)
|
||||
If the source stream is malformed, the function will stop decoding and return a negative result, indicating the byte position of the faulty instruction
|
||||
This function never writes outside of provided buffers, and never modifies input buffer.
|
||||
note : destination buffer must be already allocated.
|
||||
|
152
lz4demo.c
152
lz4demo.c
@ -102,6 +102,26 @@ static const int one = 1;
|
||||
#define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
|
||||
|
||||
|
||||
//**************************************
|
||||
// Special input/output
|
||||
//**************************************
|
||||
#define NULL_INPUT "null"
|
||||
char stdinmark[] = "stdin";
|
||||
char stdoutmark[] = "stdout";
|
||||
#ifdef _WIN32
|
||||
char nulmark[] = "nul";
|
||||
#else
|
||||
char nulmark[] = "/dev/null";
|
||||
#endif
|
||||
|
||||
|
||||
//**************************************
|
||||
// I/O Parameters
|
||||
//**************************************
|
||||
static int overwrite = 0;
|
||||
|
||||
|
||||
|
||||
//****************************
|
||||
// Functions
|
||||
//****************************
|
||||
@ -110,12 +130,13 @@ int usage(char* exename)
|
||||
DISPLAY( "Usage :\n");
|
||||
DISPLAY( " %s [arg] input output\n", exename);
|
||||
DISPLAY( "Arguments :\n");
|
||||
DISPLAY( " -c0: Fast compression (default) \n");
|
||||
DISPLAY( " -c1: High compression \n");
|
||||
DISPLAY( " -c0/-c : Fast compression (default) \n");
|
||||
DISPLAY( " -c1/-hc: High compression \n");
|
||||
DISPLAY( " -d : decompression \n");
|
||||
DISPLAY( " -b#: Benchmark files, using # compression level\n");
|
||||
DISPLAY( " -y : overwrite output \n");
|
||||
DISPLAY( " -t : check compressed file \n");
|
||||
DISPLAY( " -h : help (this text)\n");
|
||||
DISPLAY( " -b# : Benchmark files, using # compression level\n");
|
||||
DISPLAY( " -H : help (this text)\n");
|
||||
DISPLAY( "input : can be 'stdin' (pipe) or a filename\n");
|
||||
DISPLAY( "output : can be 'stdout'(pipe) or a filename or 'null'\n");
|
||||
return 0;
|
||||
@ -130,34 +151,52 @@ int badusage(char* exename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
int get_fileHandle(char* input_filename, char* output_filename, FILE** pfinput, FILE** pfoutput)
|
||||
{
|
||||
char stdinmark[] = "stdin";
|
||||
char stdoutmark[] = "stdout";
|
||||
|
||||
if (!strcmp (input_filename, stdinmark)) {
|
||||
if (!strcmp (input_filename, stdinmark))
|
||||
{
|
||||
DISPLAY( "Using stdin for input\n");
|
||||
*pfinput = stdin;
|
||||
#ifdef _WIN32 // Need to set stdin/stdout to binary mode specifically for windows
|
||||
_setmode( _fileno( stdin ), _O_BINARY );
|
||||
#endif
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
*pfinput = fopen(input_filename, "rb");
|
||||
}
|
||||
|
||||
if (!strcmp (output_filename, stdoutmark)) {
|
||||
if (!strcmp (output_filename, stdoutmark))
|
||||
{
|
||||
DISPLAY( "Using stdout for output\n");
|
||||
*pfoutput = stdout;
|
||||
#ifdef _WIN32 // Need to set stdin/stdout to binary mode specifically for windows
|
||||
_setmode( _fileno( stdout ), _O_BINARY );
|
||||
#endif
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if destination file already exists
|
||||
*pfoutput=0;
|
||||
if (output_filename != nulmark) *pfoutput = fopen( output_filename, "rb" );
|
||||
if (*pfoutput!=0)
|
||||
{
|
||||
char ch;
|
||||
fclose(*pfoutput);
|
||||
DISPLAY( "Warning : %s already exists\n", output_filename);
|
||||
if (!overwrite)
|
||||
{
|
||||
DISPLAY( "Overwrite ? (Y/N) : ");
|
||||
ch = getchar();
|
||||
if (ch!='Y') { DISPLAY( "Operation aborted : %s already exists\n", output_filename); return 12; }
|
||||
}
|
||||
}
|
||||
*pfoutput = fopen( output_filename, "wb" );
|
||||
}
|
||||
|
||||
if ( *pfinput==0 ) { DISPLAY( "Pb opening %s\n", input_filename); return 2; }
|
||||
if ( *pfoutput==0) { DISPLAY( "Pb opening %s\n", output_filename); return 3; }
|
||||
if ( *pfinput==0 ) { DISPLAY( "Pb opening %s\n", input_filename); return 13; }
|
||||
if ( *pfoutput==0) { DISPLAY( "Pb opening %s\n", output_filename); return 14; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -194,14 +233,14 @@ int compress_file(char* input_filename, char* output_filename, int compressionle
|
||||
// Allocate Memory
|
||||
in_buff = (char*)malloc(CHUNKSIZE);
|
||||
out_buff = (char*)malloc(LZ4_compressBound(CHUNKSIZE));
|
||||
if (!in_buff || !out_buff) { DISPLAY("Allocation error : not enough memory\n"); return 8; }
|
||||
if (!in_buff || !out_buff) { DISPLAY("Allocation error : not enough memory\n"); return 21; }
|
||||
|
||||
// Write Archive Header
|
||||
u32var = ARCHIVE_MAGICNUMBER;
|
||||
LITTLE_ENDIAN32(u32var);
|
||||
*(unsigned int*)out_buff = u32var;
|
||||
sizeCheck = fwrite(out_buff, 1, ARCHIVE_MAGICNUMBER_SIZE, foutput);
|
||||
if (sizeCheck!=ARCHIVE_MAGICNUMBER_SIZE) { DISPLAY("write error\n"); return 10; }
|
||||
if (sizeCheck!=ARCHIVE_MAGICNUMBER_SIZE) { DISPLAY("write error\n"); return 22; }
|
||||
|
||||
// Main Loop
|
||||
while (1)
|
||||
@ -268,13 +307,13 @@ int decode_file(char* input_filename, char* output_filename)
|
||||
// Allocate Memory
|
||||
in_buff = (char*)malloc(LZ4_compressBound(CHUNKSIZE));
|
||||
out_buff = (char*)malloc(CHUNKSIZE);
|
||||
if (!in_buff || !out_buff) { DISPLAY("Allocation error : not enough memory\n"); return 7; }
|
||||
if (!in_buff || !out_buff) { DISPLAY("Allocation error : not enough memory\n"); return 31; }
|
||||
|
||||
// Check Archive Header
|
||||
chunkSize = 0;
|
||||
uselessRet = fread(&chunkSize, 1, ARCHIVE_MAGICNUMBER_SIZE, finput);
|
||||
LITTLE_ENDIAN32(chunkSize);
|
||||
if (chunkSize != ARCHIVE_MAGICNUMBER) { DISPLAY("Unrecognized header : file cannot be decoded\n"); return 6; }
|
||||
if (chunkSize != ARCHIVE_MAGICNUMBER) { DISPLAY("Unrecognized header : file cannot be decoded\n"); return 32; }
|
||||
|
||||
// Main Loop
|
||||
while (1)
|
||||
@ -291,12 +330,12 @@ int decode_file(char* input_filename, char* output_filename)
|
||||
|
||||
// Decode Block
|
||||
sinkint = LZ4_uncompress_unknownOutputSize(in_buff, out_buff, chunkSize, CHUNKSIZE);
|
||||
if (sinkint < 0) { DISPLAY("Decoding Failed ! Corrupted input !\n"); return 9; }
|
||||
if (sinkint < 0) { DISPLAY("Decoding Failed ! Corrupted input !\n"); return 33; }
|
||||
filesize += sinkint;
|
||||
|
||||
// Write Block
|
||||
sizeCheck = fwrite(out_buff, 1, sinkint, foutput);
|
||||
if (sizeCheck != (size_t)sinkint) { DISPLAY("write error\n"); return 12; }
|
||||
if (sizeCheck != (size_t)sinkint) { DISPLAY("write error\n"); return 34; }
|
||||
}
|
||||
|
||||
// Status
|
||||
@ -327,12 +366,8 @@ int main(int argc, char** argv)
|
||||
char* exename=argv[0];
|
||||
char* input_filename=0;
|
||||
char* output_filename=0;
|
||||
#ifdef _WIN32
|
||||
char nulmark[] = "nul";
|
||||
#else
|
||||
char nulmark[] = "/dev/null";
|
||||
#endif
|
||||
char nullinput[] = "null";
|
||||
char nullinput[] = NULL_INPUT;
|
||||
char extension[] = EXTENSION;
|
||||
|
||||
// Welcome message
|
||||
DISPLAY( WELCOME_MESSAGE);
|
||||
@ -345,34 +380,64 @@ int main(int argc, char** argv)
|
||||
|
||||
if(!argument) continue; // Protection if argument empty
|
||||
|
||||
// Select command
|
||||
// Decode command (note : aggregated commands are allowed)
|
||||
if (argument[0]=='-')
|
||||
{
|
||||
while (argument[1]!=0)
|
||||
{
|
||||
argument ++;
|
||||
|
||||
switch(argument[0])
|
||||
{
|
||||
// Display help on usage
|
||||
if ( argument[0] =='h' ) { usage(exename); return 0; }
|
||||
case 'H': usage(exename); return 0;
|
||||
|
||||
// Compression (default)
|
||||
if ( argument[0] =='c' ) { if (argument[1] >='0') cLevel=argument[1] - '0'; continue; }
|
||||
case 'c': if ((argument[1] >='0') && (argument[1] <='1')) { cLevel=argument[1] - '0'; argument++; } break;
|
||||
case 'h': if (argument[1]=='c') { cLevel=1; argument++; } break;
|
||||
|
||||
// Decoding
|
||||
if ( argument[0] =='d' ) { decode=1; continue; }
|
||||
case 'd': decode=1; break;
|
||||
|
||||
// Bench
|
||||
if ( argument[0] =='b' ) { bench=1; if (argument[1] >= '0') cLevel=argument[1] - '0'; continue; }
|
||||
case 'b': bench=1;
|
||||
if ((argument[1] >='0') && (argument[1] <='1')) { cLevel=argument[1] - '0'; argument++; }
|
||||
break;
|
||||
|
||||
// Modify Block Size (benchmark only)
|
||||
if ( argument[0] =='B' ) { int B = argument[1] - '0'; int S = 1 << (10 + 2*B); BMK_SetBlocksize(S); continue; }
|
||||
case 'B':
|
||||
if ((argument[1] >='0') && (argument[1] <='9'))
|
||||
{
|
||||
int B = argument[1] - '0';
|
||||
int S = 1 << (10 + 2*B); BMK_SetBlocksize(S);
|
||||
argument++;
|
||||
}
|
||||
break;
|
||||
|
||||
// Modify Nb Iterations (benchmark only)
|
||||
if ( argument[0] =='i' ) { int iters = argument[1] - '0'; BMK_SetNbIterations(iters); continue; }
|
||||
case 'i':
|
||||
if ((argument[1] >= '0') && (argument[1] <= '9'))
|
||||
{
|
||||
int iters = argument[1] - '0';
|
||||
BMK_SetNbIterations(iters);
|
||||
argument++;
|
||||
}
|
||||
break;
|
||||
|
||||
// Pause at the end (benchmark only)
|
||||
if ( argument[0] =='p' ) { BMK_SetPause(); continue; }
|
||||
case 'p': BMK_SetPause(); break;
|
||||
|
||||
// Test
|
||||
if ( argument[0] =='t' ) { decode=1; output_filename=nulmark; continue; }
|
||||
case 't': decode=1; output_filename=nulmark; break;
|
||||
|
||||
// Overwrite
|
||||
case 'y': overwrite=1; break;
|
||||
|
||||
// Unrecognised command
|
||||
default : badusage(exename); return 1;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// first provided filename is input
|
||||
@ -392,8 +457,23 @@ int main(int argc, char** argv)
|
||||
|
||||
if (bench) return BMK_benchFile(argv+filenamesStart, argc-filenamesStart, cLevel);
|
||||
|
||||
// No output filename ==> Error
|
||||
if (!output_filename) { badusage(exename); return 1; }
|
||||
// No output filename ==> build one automatically (for compression only)
|
||||
if (!output_filename)
|
||||
{
|
||||
if (!decode)
|
||||
{
|
||||
int i=0, l=0;
|
||||
while (input_filename[l]!=0) l++;
|
||||
output_filename = (char*)calloc(1,l+5);
|
||||
for (i=0;i<l;i++) output_filename[i] = input_filename[i];
|
||||
for (i=l;i<l+4;i++) output_filename[i] = extension[i-l];
|
||||
}
|
||||
else
|
||||
{
|
||||
badusage(exename);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (decode) return decode_file(input_filename, output_filename);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user