// Includes\r
//**************************************\r
#include <stdlib.h>\r
-#include <stdio.h> // fgets\r
+#include <stdio.h> // fgets, sscanf\r
#include <sys/timeb.h> // timeb\r
#include "lz4.h"\r
\r
unsigned long long bytes = 0;\r
unsigned long long cbytes = 0;\r
unsigned char buf[LEN];\r
-# define FUZ_max LZ4_compressBound(LEN)\r
+ unsigned char testOut[LEN+1];\r
+# define FUZ_max LZ4_COMPRESSBOUND(LEN)\r
# define FUZ_avail ROUND_PAGE(FUZ_max)\r
const int off_full = FUZ_avail - FUZ_max;\r
unsigned char cbuf[FUZ_avail + PAGE_SIZE];\r
- unsigned int seed, cur_seq, seeds[NUM_SEQ], timestamp=FUZ_GetMilliStart();\r
+ unsigned int seed, cur_seq=PRIME3, seeds[NUM_SEQ], timestamp=FUZ_GetMilliStart();\r
int i, j, k, ret, len;\r
char userInput[30] = {0};\r
\r
\r
for (i = 0; i < NB_ATTEMPTS; i++) {\r
printf("\r%7i /%7i\r", i, NB_ATTEMPTS);\r
+ \r
FUZ_rand(&seed);\r
for (j = 0; j < NUM_SEQ; j++) {\r
seeds[j] = FUZ_rand(&seed) << 8;\r
}\r
buf[j] = FUZ_rand(&cur_seq) >> 16;\r
}\r
+\r
+ // Test compression\r
ret = LZ4_compress_limitedOutput((const char*)buf, (char*)&cbuf[off_full], LEN, FUZ_max);\r
+ if (ret == 0) { printf("compression failed despite sufficient space: seed %u, len %d\n", seed, LEN); goto _output_error; }\r
len = ret;\r
\r
- // Test compression with output size being exactly what's necessary\r
+ // Test decoding with output size being exactly what's necessary => must work\r
+ ret = LZ4_uncompress((char*)&cbuf[off_full], (char*)testOut, LEN);\r
+ if (ret<0) { printf("decompression failed despite sufficient space: seed %u, len %d\n", seed, LEN); goto _output_error; }\r
+\r
+ // Test decoding with one byte missing => must fail\r
+ ret = LZ4_uncompress((char*)&cbuf[off_full], (char*)testOut, LEN-1);\r
+ if (ret>=0) { printf("decompression should have failed, due to Output Size being too small : seed %u, len %d\n", seed, LEN); goto _output_error; }\r
+\r
+ // Test decoding with one byte too much => must fail\r
+ ret = LZ4_uncompress((char*)&cbuf[off_full], (char*)testOut, LEN+1);\r
+ if (ret>=0) { printf("decompression should have failed, due to Output Size being too large : seed %u, len %d\n", seed, LEN); goto _output_error; }\r
+\r
+ // Test decoding with enough output size => must work\r
+ ret = LZ4_uncompress_unknownOutputSize((char*)&cbuf[off_full], (char*)testOut, len, LEN+1);\r
+ if (ret<0) { printf("decompression failed despite sufficient space: seed %u, len %d\n", seed, LEN); goto _output_error; }\r
+\r
+ // Test decoding with output size being exactly what's necessary => should work\r
+ ret = LZ4_uncompress_unknownOutputSize((char*)&cbuf[off_full], (char*)testOut, len, LEN);\r
+ if (ret<0) { printf("decompression failed despite sufficient space: seed %u, len %d\n", seed, LEN); goto _output_error; }\r
+\r
+ // Test decoding with output size being one byte too short => must fail\r
+ ret = LZ4_uncompress_unknownOutputSize((char*)&cbuf[off_full], (char*)testOut, len, LEN-1);\r
+ if (ret>=0) { printf("decompression should have failed, due to Output Size being too small : seed %u, len %d\n", seed, LEN); goto _output_error; }\r
+\r
+ // Test decoding with input size being one byte too short => must fail\r
+ ret = LZ4_uncompress_unknownOutputSize((char*)&cbuf[off_full], (char*)testOut, len-1, LEN);\r
+ if (ret>=0) { printf("decompression should have failed, due to input size being too small : seed %u, len %d\n", seed, LEN); goto _output_error; }\r
+\r
+ // Test decoding with input size being one byte too large => must fail\r
+ ret = LZ4_uncompress_unknownOutputSize((char*)&cbuf[off_full], (char*)testOut, len+1, LEN);\r
+ if (ret>=0) { printf("decompression should have failed, due to input size being too large : seed %u, len %d\n", seed, LEN); goto _output_error; }\r
+\r
+ // Test compression with output size being exactly what's necessary (should work)\r
ret = LZ4_compress_limitedOutput((const char*)buf, (char*)&cbuf[FUZ_avail-len], LEN, len);\r
- if (!test_canary(&cbuf[FUZ_avail])) { printf("compression overran output buffer: seed %u, len %d, olen %d\n", seed, LEN, len); return 1; }\r
- if (ret == 0) { printf("compression failed despite sufficient space: seed %u, len %d\n", seed, LEN); return 1; }\r
+ if (!test_canary(&cbuf[FUZ_avail])) { printf("compression overran output buffer: seed %u, len %d, olen %d\n", seed, LEN, len); goto _output_error; }\r
+ if (ret == 0) { printf("compression failed despite sufficient space: seed %u, len %d\n", seed, LEN); goto _output_error; }\r
\r
// Test compression with just one missing byte into output buffer => must fail\r
ret = LZ4_compress_limitedOutput((const char*)buf, (char*)&cbuf[FUZ_avail-(len-1)], LEN, len-1);\r
- if (ret) { printf("compression overran output buffer: seed %u, len %d, olen %d => ret %d", seed, LEN, len-1, ret); return 1; }\r
- if (!test_canary(&cbuf[FUZ_avail])) { printf("compression overran output buffer: seed %u, len %d, olen %d", seed, LEN, len-1); return 1; }\r
+ if (ret) { printf("compression overran output buffer: seed %u, len %d, olen %d => ret %d", seed, LEN, len-1, ret); goto _output_error; }\r
+ if (!test_canary(&cbuf[FUZ_avail])) { printf("compression overran output buffer: seed %u, len %d, olen %d", seed, LEN, len-1); goto _output_error; }\r
\r
bytes += LEN;\r
cbytes += len;\r
}\r
+\r
printf("all tests completed successfully \n");\r
printf("compression ratio: %0.3f%%\n", (double)cbytes/bytes*100);\r
+ getchar();\r
return 0;\r
+\r
+_output_error:\r
+ getchar();\r
+ return 1;\r
}\r
#endif\r
\r
\r
+//**************************************\r
+// Compiler Options\r
+//**************************************\r
+#ifdef _MSC_VER // Visual Studio\r
+# define inline __inline // Visual is not C99, but supports some kind of inline\r
+#endif\r
+\r
+\r
//****************************\r
// Simple Functions\r
//****************************\r
Compresses 'isize' bytes from 'source' into 'dest'.\r
Destination buffer must be already allocated,\r
and must be sized to handle worst cases situations (input data not compressible)\r
- Worst case size evaluation is provided by macro LZ4_compressBound()\r
+ Worst case size evaluation is provided by function LZ4_compressBound()\r
\r
isize : is the input size. Max supported value is ~1.9GB\r
return : the number of bytes written in buffer dest\r
// Advanced Functions\r
//****************************\r
\r
-#define LZ4_compressBound(isize) (isize + (isize/255) + 16)\r
+static inline int LZ4_compressBound(int isize) { return ((isize) + ((isize)/255) + 16); }\r
+#define LZ4_COMPRESSBOUND( isize) ((isize) + ((isize)/255) + 16)\r
\r
/*\r
LZ4_compressBound() :\r
Provides the maximum size that LZ4 may output in a "worst case" scenario (input data not compressible)\r
primarily useful for memory allocation of output buffer.\r
+ inline function is recommended for the general case,\r
+ but macro is also provided when results need to be evaluated at compile time (such as table size allocation).\r
\r
isize : is the input size. Max supported value is ~1.9GB\r
return : maximum output size in a "worst case" scenario\r
\r
\r
//**************************************\r
-// Compiler functions\r
+// Compiler-specific functions\r
//**************************************\r
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)\r
\r
// Architecture Macros\r
//**************************************\r
static const int one = 1;\r
-#define CPU_LITTLE_ENDIAN (*(char*)(&one))\r
-#define CPU_BIG_ENDIAN (!CPU_LITTLE_ENDIAN)\r
-#define LITTLE_ENDIAN32(i) if (CPU_BIG_ENDIAN) { i = swap32(i); }\r
+#define CPU_LITTLE_ENDIAN (*(char*)(&one))\r
+#define CPU_BIG_ENDIAN (!CPU_LITTLE_ENDIAN)\r
+#define LITTLE_ENDIAN32(i) if (CPU_BIG_ENDIAN) { i = swap32(i); }\r
\r
\r
//**************************************\r
int r;\r
int displayLevel = (compressionlevel>0);\r
clock_t start, end;\r
+ size_t sizeCheck;\r
\r
\r
// Init\r
u32var = ARCHIVE_MAGICNUMBER;\r
LITTLE_ENDIAN32(u32var);\r
*(unsigned int*)out_buff = u32var;\r
- fwrite(out_buff, 1, ARCHIVE_MAGICNUMBER_SIZE, foutput);\r
+ sizeCheck = fwrite(out_buff, 1, ARCHIVE_MAGICNUMBER_SIZE, foutput);\r
+ if (sizeCheck!=ARCHIVE_MAGICNUMBER_SIZE) { DISPLAY("write error\n"); return 10; }\r
\r
// Main Loop\r
while (1)\r
LITTLE_ENDIAN32(outSize);\r
* (unsigned int*) out_buff = outSize;\r
LITTLE_ENDIAN32(outSize);\r
- fwrite(out_buff, 1, outSize+4, foutput);\r
+ sizeCheck = fwrite(out_buff, 1, outSize+4, foutput);\r
+ if (sizeCheck!=(size_t)(outSize+4)) { DISPLAY("write error\n"); return 11; }\r
}\r
\r
// Status\r
FILE* foutput;\r
clock_t start, end;\r
int r;\r
+ size_t sizeCheck;\r
\r
\r
// Init\r
filesize += sinkint;\r
\r
// Write Block\r
- fwrite(out_buff, 1, sinkint, foutput);\r
+ sizeCheck = fwrite(out_buff, 1, sinkint, foutput);\r
+ if (sizeCheck != (size_t)sinkint) { DISPLAY("write error\n"); return 12; }\r
}\r
\r
// Status\r