Skip to content

Commit b0ab517

Browse files
committed
Test application improvements:
- added possibility to load external zlib dll under windows and use its compression instead of builtin - improved output information: new data provided, new layout - added possibility to specify compression level - added possibility to exclude particular directory (or many directories) from data input - added option for removal of compressed file - using different gz file names for different platforms (just to run compression tests in parallel from win32, win64 and/or linux VM)
1 parent ae858ac commit b0ab517

File tree

4 files changed

+230
-15
lines changed

4 files changed

+230
-15
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ zlib/
44
*.exe
55
*.pdb
66
build/binaries/
7+
Test/dll/

Test/dll/readme.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Put zlibwapi.dll from http://www.winimage.com/zLibDll/ here. Names used by test.sh script are zlibwapi32.dll and zlibwapi64.dll.

Test/test.cpp

+203-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
24
#include <time.h>
35

46
// includes for file enumeration
57
#if _WIN32
68
# include <io.h> // for findfirst() set
9+
# ifndef _WIN64
10+
# define PLATFORM "win32"
11+
# else
12+
# define PLATFORM "win64"
13+
# endif
714
#else
815
# include <dirent.h> // for opendir() etc
916
# include <sys/stat.h> // for stat()
17+
# define stricmp strcasecmp
18+
# define strnicmp strncasecmp
19+
# define PLATFORM "unix"
1020
#endif
1121

1222
#include <vector>
@@ -21,7 +31,88 @@
2131
#define MAX_ITERATIONS 1 // number of passes to fully fill buffer, i.e. total processed data size will be up to (BUFFER_SIZE * MAX_ITERATIONS)
2232
#define COMPRESS_LEVEL 9
2333

34+
#if _WIN32
35+
36+
#include <windows.h>
37+
38+
static HMODULE zlibDll = NULL;
39+
40+
static gzFile gzopen_imp(const char* filename, const char* params)
41+
{
42+
if (zlibDll)
43+
{
44+
typedef gzFile (WINAPI *gzopen_f)(const char* filename, const char* params);
45+
static gzopen_f gzopen_ptr = NULL;
46+
if (gzopen_ptr == NULL)
47+
{
48+
gzopen_ptr = (gzopen_f)GetProcAddress(zlibDll, "gzopen");
49+
// assert(gzopen_ptr);
50+
}
51+
return gzopen_ptr(filename, params);
52+
}
53+
else
54+
{
55+
return gzopen(filename, params);
56+
}
57+
}
58+
59+
static int gzwrite_imp(gzFile file, voidpc buf, unsigned len)
60+
{
61+
if (zlibDll)
62+
{
63+
typedef int (WINAPI *gzwrite_f)(gzFile file, voidpc buf, unsigned len);
64+
static gzwrite_f gzwrite_ptr = NULL;
65+
if (gzwrite_ptr == NULL)
66+
{
67+
gzwrite_ptr = (gzwrite_f)GetProcAddress(zlibDll, "gzwrite");
68+
// assert(gzwrite_ptr);
69+
}
70+
return gzwrite_ptr(file, buf, len);
71+
}
72+
else
73+
{
74+
return gzwrite(file, buf, len);
75+
}
76+
}
77+
78+
static int gzclose_imp(gzFile file)
79+
{
80+
if (zlibDll)
81+
{
82+
typedef int (WINAPI *gzclose_f)(gzFile file);
83+
static gzclose_f gzclose_ptr = NULL;
84+
if (gzclose_ptr == NULL)
85+
{
86+
gzclose_ptr = (gzclose_f)GetProcAddress(zlibDll, "gzclose");
87+
// assert(gzclose_ptr);
88+
}
89+
return gzclose_ptr(file);
90+
}
91+
else
92+
{
93+
return gzclose(file);
94+
}
95+
}
96+
97+
// Hook gzip functions
98+
#define gzopen gzopen_imp
99+
#define gzwrite gzwrite_imp
100+
#define gzclose gzclose_imp
101+
102+
#endif // _WIN32
103+
24104
std::vector<std::string> fileList;
105+
std::vector<std::string> fileExclude;
106+
107+
static bool IsFileExcluded(const char* filename)
108+
{
109+
for (int i = 0; i < fileExclude.size(); i++)
110+
{
111+
if (!stricmp(filename, fileExclude[i].c_str()))
112+
return true;
113+
}
114+
return false;
115+
}
25116

26117
static bool ScanDirectory(const char *dir, bool recurse = true)
27118
{
@@ -37,6 +128,7 @@ static bool ScanDirectory(const char *dir, bool recurse = true)
37128
{
38129
if (found.name[0] == '.') continue; // "." or ".."
39130
sprintf(Path, "%s/%s", dir, found.name);
131+
if (IsFileExcluded(Path)) continue;
40132
// directory -> recurse
41133
if (found.attrib & _A_SUBDIR)
42134
{
@@ -60,6 +152,7 @@ static bool ScanDirectory(const char *dir, bool recurse = true)
60152
{
61153
if (ent->d_name[0] == '.') continue; // "." or ".."
62154
sprintf(Path, "%s/%s", dir, ent->d_name);
155+
if (IsFileExcluded(Path)) continue;
63156
// directory -> recurse
64157
// note: using 'stat64' here because 'stat' ignores large files
65158
struct stat64 buf;
@@ -113,19 +206,100 @@ int main(int argc, const char **argv)
113206
{
114207
if (argc <= 1)
115208
{
116-
printf("Usage: test <directory>\n");
209+
usage:
210+
printf(
211+
"Usage: test [options] <directory>\n"
212+
"Options:\n"
213+
" --level=[0-9] set compression level, default 9\n"
214+
" --exclude=<dir> exclude specified directory from tests\n"
215+
#if _WIN32
216+
" --dll=<file> use external WINAPI zlib dll\n"
217+
#endif
218+
" --compact use compact output\n"
219+
" --delete erase compressed file after completion\n"
220+
);
117221
return 1;
118222
}
119223

120-
ScanDirectory(argv[1]);
224+
// parse command line
225+
const char* dirName = NULL;
226+
char level = '9';
227+
bool compactOutput = false;
228+
bool eraseCompressedFile = false;
229+
230+
for (int i = 1; i < argc; i++)
231+
{
232+
const char* arg = argv[i];
233+
if (arg[0] == '-' && arg[1] == '-')
234+
{
235+
// option
236+
arg += 2; // skip "--"
237+
if (!strnicmp(arg, "level=", 6))
238+
{
239+
if (!(level >= '0' && level <= '9')) goto usage;
240+
level = arg[6];
241+
}
242+
else if (!strnicmp(arg, "exclude=", 8))
243+
{
244+
fileExclude.push_back(arg+8);
245+
}
246+
else if (!stricmp(arg, "compact"))
247+
{
248+
compactOutput = true;
249+
}
250+
else if (!stricmp(arg, "delete"))
251+
{
252+
eraseCompressedFile = true;
253+
}
254+
#if _WIN32
255+
else if (!strnicmp(arg, "dll=", 4))
256+
{
257+
if (zlibDll != NULL) goto usage;
258+
zlibDll = LoadLibrary(arg+4);
259+
if (zlibDll == NULL)
260+
{
261+
printf("Error: unable to load zlib.dll %s\n", arg+4);
262+
exit(1);
263+
}
264+
}
265+
#endif // _WIN32
266+
else
267+
{
268+
goto usage;
269+
}
270+
}
271+
else
272+
{
273+
if (dirName) goto usage;
274+
dirName = arg;
275+
}
276+
}
277+
278+
if (!dirName)
279+
{
280+
printf("Error: directory name was not specified\n");
281+
exit(1);
282+
}
283+
284+
// prepare data for compression
285+
ScanDirectory(dirName);
286+
if (fileList.size() == 0)
287+
{
288+
printf("Error: the specified location has no files\n");
289+
exit(1);
290+
}
121291
// printf("%d files\n", fileList.size());
122292

123293
clock_t clocks = 0;
124294

125-
const char* compressedFile = "compressed-" STR(VERSION) ".gz";
126-
gzFile gz = gzopen(compressedFile, "wb" STR(COMPRESS_LEVEL));
295+
// open compressed stream
296+
char initString[4] = "wb";
297+
const char* compressedFile = "compressed-" STR(VERSION) "-" PLATFORM ".gz";
298+
initString[2] = level;
299+
gzFile gz = gzopen(compressedFile, initString);
127300
int iteration = 0;
128301
int totalDataSize = 0;
302+
// perform compression
129303
while (FillBuffer() && iteration < MAX_ITERATIONS)
130304
{
131305
clock_t clock_a = clock();
@@ -134,16 +308,38 @@ int main(int argc, const char **argv)
134308
iteration++;
135309
totalDataSize += bytesInBuffer;
136310
}
311+
// close compressed stream
137312
gzclose(gz);
138313

314+
// determine size of compressed data
139315
FILE* f = fopen(compressedFile, "rb");
140316
fseek(f, 0, SEEK_END);
141317
int compressedSize = ftell(f);
142318
fclose(f);
143319

144-
printf("Compressed %.1f Mb of data by method %s with level %d (%s)\n", (float)totalDataSize / (1024*1024), STR(VERSION), COMPRESS_LEVEL, argv[1]);
145-
printf("Time: %.1f s\n", clocks / (float)CLOCKS_PER_SEC);
146-
printf("Size: %d\n", compressedSize);
320+
// erase compressed file
321+
if (eraseCompressedFile)
322+
{
323+
remove(compressedFile);
324+
}
325+
326+
// print results
327+
const char* method = STR(VERSION);
328+
#if _WIN32
329+
if (zlibDll) method = "DLL";
330+
#endif
331+
float time = clocks / (float)CLOCKS_PER_SEC;
332+
float originalSizeMb = totalDataSize / double(1<<20);
333+
if (!compactOutput)
334+
{
335+
printf("Compressed %.1f Mb of data by method %s with level %c (%s)\n", originalSizeMb, method, level, dirName);
336+
}
337+
else
338+
{
339+
printf("%6s:%c Data: %.1f Mb ", method, level, originalSizeMb);
340+
}
341+
printf("Time: %-5.1f s Size: %d bytes Speed: %5.2f Mb/s Ratio: %.2f\n",
342+
time, compressedSize, totalDataSize / double(1<<20) / time, (double)totalDataSize / compressedSize);
147343

148344
return 0;
149345
}

test.sh

+25-8
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22

33
platform=win32
44

5+
noorig=0
6+
noasm=0
7+
nodll=0
8+
extraargs="--delete --compact"
9+
dllname=zlibwapi32.dll
10+
511
if [ "$OSTYPE" == "linux-gnu" ] || [ "$OSTYPE" == "linux" ]; then
612
platform=unix
13+
nodll=1
714
fi
815

9-
noorig=0
10-
noasm=0
11-
1216
for arg in "$@"; do # using quoted $@ will allow to correctly separate arguments like [ --path="some string with spaces" -debug ]
1317
# echo "ARG=$arg"
1418
case $arg in
@@ -18,14 +22,21 @@ for arg in "$@"; do # using quoted $@ will allow to correctly separate argument
1822
--noorig)
1923
noorig=1
2024
;;
25+
--nodll)
26+
nodll=1
27+
;;
2128
--win64)
2229
platform=win64
30+
dllname=zlibwapi64.dll
31+
;;
32+
--level=*|--exclude=*)
33+
extraargs="$extraargs $arg"
2334
;;
2435
*)
2536
if [ -d "$arg" ]; then
2637
dir="$arg"
2738
else
28-
echo "Usage: test.sh [path] [--noasm] [--noorig] [--win64]"
39+
echo "Usage: test.sh [path] [--noasm] [--noorig] [--nodll] [--win64] [--level=X]"
2940
exit
3041
fi
3142
esac
@@ -45,6 +56,9 @@ echo "Testing for $platform"
4556
function DoTests
4657
{
4758
local dir="$1"
59+
shift
60+
61+
echo "--- Processing data at $dir ---"
4862

4963
if [ "$platform" == "unix" ]; then
5064
# convert Windows path to Linux (VM)
@@ -54,18 +68,21 @@ function DoTests
5468
fi
5569

5670
if [ "$platform" != "win64" ] && [ $noasm == 0 ]; then
57-
obj/bin/test-Asm-$platform "$dir"
71+
obj/bin/test-Asm-$platform "$dir" $extraargs $*
72+
fi
73+
obj/bin/test-C-$platform "$dir" $extraargs $*
74+
if [ $nodll == 0 ]; then
75+
obj/bin/test-Orig-$platform "$dir" $extraargs --dll=test/dll/$dllname $*
5876
fi
59-
obj/bin/test-C-$platform "$dir"
6077
if [ $noorig == 0 ]; then
61-
obj/bin/test-Orig-$platform "$dir"
78+
obj/bin/test-Orig-$platform "$dir" $extraargs $*
6279
fi
6380
}
6481

6582
if [ "$dir" ]; then
6683
DoTests "$dir"
6784
else
68-
DoTests C:/Projects/Epic/UnrealEngine4-latest/Engine/Source/Runtime
85+
DoTests C:/Projects/Epic/UnrealEngine4-latest/Engine/Source --exclude=ThirdParty
6986
DoTests C:/3-UnrealEngine/4.14/Engine/Binaries/Win64
7087
DoTests C:/1
7188
fi

0 commit comments

Comments
 (0)