libdeflate 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.gitmodules +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +9 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +52 -0
- data/Rakefile +15 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/libdeflate/extconf.rb +14 -0
- data/ext/libdeflate/libdeflate/.gitignore +19 -0
- data/ext/libdeflate/libdeflate/COPYING +21 -0
- data/ext/libdeflate/libdeflate/Makefile +231 -0
- data/ext/libdeflate/libdeflate/Makefile.msc +64 -0
- data/ext/libdeflate/libdeflate/NEWS +57 -0
- data/ext/libdeflate/libdeflate/README.md +170 -0
- data/ext/libdeflate/libdeflate/common/common_defs.h +351 -0
- data/ext/libdeflate/libdeflate/common/compiler_gcc.h +134 -0
- data/ext/libdeflate/libdeflate/common/compiler_msc.h +95 -0
- data/ext/libdeflate/libdeflate/lib/adler32.c +213 -0
- data/ext/libdeflate/libdeflate/lib/adler32_impl.h +281 -0
- data/ext/libdeflate/libdeflate/lib/aligned_malloc.c +57 -0
- data/ext/libdeflate/libdeflate/lib/aligned_malloc.h +13 -0
- data/ext/libdeflate/libdeflate/lib/bt_matchfinder.h +357 -0
- data/ext/libdeflate/libdeflate/lib/crc32.c +368 -0
- data/ext/libdeflate/libdeflate/lib/crc32_impl.h +286 -0
- data/ext/libdeflate/libdeflate/lib/crc32_table.h +526 -0
- data/ext/libdeflate/libdeflate/lib/decompress_impl.h +404 -0
- data/ext/libdeflate/libdeflate/lib/deflate_compress.c +2817 -0
- data/ext/libdeflate/libdeflate/lib/deflate_compress.h +14 -0
- data/ext/libdeflate/libdeflate/lib/deflate_constants.h +66 -0
- data/ext/libdeflate/libdeflate/lib/deflate_decompress.c +889 -0
- data/ext/libdeflate/libdeflate/lib/gzip_compress.c +95 -0
- data/ext/libdeflate/libdeflate/lib/gzip_constants.h +45 -0
- data/ext/libdeflate/libdeflate/lib/gzip_decompress.c +130 -0
- data/ext/libdeflate/libdeflate/lib/hc_matchfinder.h +405 -0
- data/ext/libdeflate/libdeflate/lib/lib_common.h +35 -0
- data/ext/libdeflate/libdeflate/lib/matchfinder_avx2.h +53 -0
- data/ext/libdeflate/libdeflate/lib/matchfinder_common.h +205 -0
- data/ext/libdeflate/libdeflate/lib/matchfinder_neon.h +61 -0
- data/ext/libdeflate/libdeflate/lib/matchfinder_sse2.h +53 -0
- data/ext/libdeflate/libdeflate/lib/unaligned.h +202 -0
- data/ext/libdeflate/libdeflate/lib/x86_cpu_features.c +169 -0
- data/ext/libdeflate/libdeflate/lib/x86_cpu_features.h +48 -0
- data/ext/libdeflate/libdeflate/lib/zlib_compress.c +87 -0
- data/ext/libdeflate/libdeflate/lib/zlib_constants.h +21 -0
- data/ext/libdeflate/libdeflate/lib/zlib_decompress.c +91 -0
- data/ext/libdeflate/libdeflate/libdeflate.h +274 -0
- data/ext/libdeflate/libdeflate/programs/benchmark.c +558 -0
- data/ext/libdeflate/libdeflate/programs/checksum.c +197 -0
- data/ext/libdeflate/libdeflate/programs/detect.sh +62 -0
- data/ext/libdeflate/libdeflate/programs/gzip.c +603 -0
- data/ext/libdeflate/libdeflate/programs/prog_util.c +530 -0
- data/ext/libdeflate/libdeflate/programs/prog_util.h +162 -0
- data/ext/libdeflate/libdeflate/programs/test_checksums.c +135 -0
- data/ext/libdeflate/libdeflate/programs/tgetopt.c +118 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/Makefile +12 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_compress/fuzz.c +40 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_compress/inputs/0 +0 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_decompress/fuzz.c +28 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_decompress/inputs/0 +3 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/gzip_decompress/fuzz.c +28 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/gzip_decompress/inputs/0 +0 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/prepare_for_fuzz.sh +14 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/zlib_decompress/fuzz.c +28 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/zlib_decompress/inputs/0 +3 -0
- data/ext/libdeflate/libdeflate/tools/android_build.sh +104 -0
- data/ext/libdeflate/libdeflate/tools/checksum_benchmarks.sh +76 -0
- data/ext/libdeflate/libdeflate/tools/exec_tests.sh +30 -0
- data/ext/libdeflate/libdeflate/tools/gen_crc32_multipliers.c +108 -0
- data/ext/libdeflate/libdeflate/tools/gen_crc32_table.c +100 -0
- data/ext/libdeflate/libdeflate/tools/gzip_tests.sh +412 -0
- data/ext/libdeflate/libdeflate/tools/make-windows-releases +21 -0
- data/ext/libdeflate/libdeflate/tools/mips_build.sh +9 -0
- data/ext/libdeflate/libdeflate/tools/msc_test.bat +3 -0
- data/ext/libdeflate/libdeflate/tools/pgo_build.sh +23 -0
- data/ext/libdeflate/libdeflate/tools/produce_gzip_benchmark_table.sh +37 -0
- data/ext/libdeflate/libdeflate/tools/run_tests.sh +305 -0
- data/ext/libdeflate/libdeflate/tools/windows_build.sh +10 -0
- data/ext/libdeflate/libdeflate_ext.c +389 -0
- data/ext/libdeflate/libdeflate_ext.h +8 -0
- data/lib/libdeflate.rb +2 -0
- data/lib/libdeflate/version.rb +3 -0
- data/libdeflate.gemspec +33 -0
- metadata +230 -0
@@ -0,0 +1,162 @@
|
|
1
|
+
/*
|
2
|
+
* prog_util.h - utility functions for programs
|
3
|
+
*
|
4
|
+
* Copyright 2016 Eric Biggers
|
5
|
+
*
|
6
|
+
* Permission is hereby granted, free of charge, to any person
|
7
|
+
* obtaining a copy of this software and associated documentation
|
8
|
+
* files (the "Software"), to deal in the Software without
|
9
|
+
* restriction, including without limitation the rights to use,
|
10
|
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
* copies of the Software, and to permit persons to whom the
|
12
|
+
* Software is furnished to do so, subject to the following
|
13
|
+
* conditions:
|
14
|
+
*
|
15
|
+
* The above copyright notice and this permission notice shall be
|
16
|
+
* included in all copies or substantial portions of the Software.
|
17
|
+
*
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20
|
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22
|
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23
|
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24
|
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25
|
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26
|
+
*/
|
27
|
+
|
28
|
+
#ifndef PROGRAMS_PROG_UTIL_H
|
29
|
+
#define PROGRAMS_PROG_UTIL_H
|
30
|
+
|
31
|
+
#ifdef HAVE_CONFIG_H
|
32
|
+
# include "config.h"
|
33
|
+
#endif
|
34
|
+
|
35
|
+
#include "libdeflate.h"
|
36
|
+
|
37
|
+
#include <limits.h>
|
38
|
+
#include <stdio.h>
|
39
|
+
#include <stdlib.h>
|
40
|
+
#include <string.h>
|
41
|
+
|
42
|
+
#include "common_defs.h"
|
43
|
+
|
44
|
+
#ifdef __GNUC__
|
45
|
+
# define _printf(str_idx, args_idx) \
|
46
|
+
__attribute__((format(printf, str_idx, args_idx)))
|
47
|
+
#else
|
48
|
+
# define _printf(str_idx, args_idx)
|
49
|
+
#endif
|
50
|
+
|
51
|
+
#ifdef _WIN32
|
52
|
+
|
53
|
+
/*
|
54
|
+
* Definitions for Windows builds. Mainly, 'tchar' is defined to be the 2-byte
|
55
|
+
* 'wchar_t' type instead of 'char'. This is the only "easy" way I know of to
|
56
|
+
* get full Unicode support on Windows...
|
57
|
+
*/
|
58
|
+
|
59
|
+
#include <wchar.h>
|
60
|
+
extern int wmain(int argc, wchar_t **argv);
|
61
|
+
# define tmain wmain
|
62
|
+
# define tchar wchar_t
|
63
|
+
# define _T(text) L##text
|
64
|
+
# define T(text) _T(text)
|
65
|
+
# define TS "ls"
|
66
|
+
# define TC "lc"
|
67
|
+
# define tmemcpy wmemcpy
|
68
|
+
# define topen _wopen
|
69
|
+
# define tstrchr wcschr
|
70
|
+
# define tstrcmp wcscmp
|
71
|
+
# define tstrcpy wcscpy
|
72
|
+
# define tstrlen wcslen
|
73
|
+
# define tstrrchr wcsrchr
|
74
|
+
# define tstrtoul wcstoul
|
75
|
+
# define tstrxcmp wcsicmp
|
76
|
+
# define tunlink _wunlink
|
77
|
+
# define tutimbuf __utimbuf64
|
78
|
+
# define tutime _wutime64
|
79
|
+
# define tstat _wstat64
|
80
|
+
# define tfstat _fstat64
|
81
|
+
# define stat_t struct _stat64
|
82
|
+
# ifdef _MSC_VER
|
83
|
+
# define STDIN_FILENO 0
|
84
|
+
# define STDOUT_FILENO 1
|
85
|
+
# define STDERR_FILENO 2
|
86
|
+
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
87
|
+
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
88
|
+
# endif
|
89
|
+
|
90
|
+
#else /* _WIN32 */
|
91
|
+
|
92
|
+
/* Standard definitions for everyone else */
|
93
|
+
|
94
|
+
# define tmain main
|
95
|
+
# define tchar char
|
96
|
+
# define T(text) text
|
97
|
+
# define TS "s"
|
98
|
+
# define TC "c"
|
99
|
+
# define tmemcpy memcpy
|
100
|
+
# define topen open
|
101
|
+
# define tstrchr strchr
|
102
|
+
# define tstrcmp strcmp
|
103
|
+
# define tstrcpy strcpy
|
104
|
+
# define tstrlen strlen
|
105
|
+
# define tstrrchr strrchr
|
106
|
+
# define tstrtoul strtoul
|
107
|
+
# define tstrxcmp strcmp
|
108
|
+
# define tunlink unlink
|
109
|
+
# define tutimbuf utimbuf
|
110
|
+
# define tutime utime
|
111
|
+
# define tstat stat
|
112
|
+
# define tfstat fstat
|
113
|
+
# define stat_t struct stat
|
114
|
+
|
115
|
+
#endif /* !_WIN32 */
|
116
|
+
|
117
|
+
extern const tchar *program_invocation_name;
|
118
|
+
|
119
|
+
extern void _printf(1, 2) msg(const char *fmt, ...);
|
120
|
+
extern void _printf(1, 2) msg_errno(const char *fmt, ...);
|
121
|
+
|
122
|
+
extern void *xmalloc(size_t size);
|
123
|
+
|
124
|
+
extern u64 timer_ticks(void);
|
125
|
+
extern u64 timer_ticks_to_ms(u64 ticks);
|
126
|
+
extern u64 timer_MB_per_s(u64 bytes, u64 ticks);
|
127
|
+
|
128
|
+
extern const tchar *get_filename(const tchar *path);
|
129
|
+
|
130
|
+
struct file_stream {
|
131
|
+
int fd;
|
132
|
+
tchar *name;
|
133
|
+
bool is_standard_stream;
|
134
|
+
void *mmap_token;
|
135
|
+
void *mmap_mem;
|
136
|
+
size_t mmap_size;
|
137
|
+
};
|
138
|
+
|
139
|
+
extern int xopen_for_read(const tchar *path, bool symlink_ok,
|
140
|
+
struct file_stream *strm);
|
141
|
+
extern int xopen_for_write(const tchar *path, bool force,
|
142
|
+
struct file_stream *strm);
|
143
|
+
extern int map_file_contents(struct file_stream *strm, u64 size);
|
144
|
+
|
145
|
+
extern ssize_t xread(struct file_stream *strm, void *buf, size_t count);
|
146
|
+
extern int full_write(struct file_stream *strm, const void *buf, size_t count);
|
147
|
+
|
148
|
+
extern int xclose(struct file_stream *strm);
|
149
|
+
|
150
|
+
extern int parse_compression_level(tchar opt_char, const tchar *arg);
|
151
|
+
|
152
|
+
extern struct libdeflate_compressor *alloc_compressor(int level);
|
153
|
+
extern struct libdeflate_decompressor *alloc_decompressor(void);
|
154
|
+
|
155
|
+
/* tgetopt.c */
|
156
|
+
|
157
|
+
extern tchar *toptarg;
|
158
|
+
extern int toptind, topterr, toptopt;
|
159
|
+
|
160
|
+
extern int tgetopt(int argc, tchar *argv[], const tchar *optstring);
|
161
|
+
|
162
|
+
#endif /* PROGRAMS_PROG_UTIL_H */
|
@@ -0,0 +1,135 @@
|
|
1
|
+
/*
|
2
|
+
* test_checksums.c
|
3
|
+
*
|
4
|
+
* Verify that libdeflate's Adler-32 and CRC-32 functions produce the same
|
5
|
+
* results as their zlib equivalents.
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include <time.h>
|
9
|
+
#include <zlib.h>
|
10
|
+
|
11
|
+
#include "prog_util.h"
|
12
|
+
|
13
|
+
static unsigned int rng_seed;
|
14
|
+
|
15
|
+
static void
|
16
|
+
assertion_failed(const char *file, int line)
|
17
|
+
{
|
18
|
+
fprintf(stderr, "Assertion failed at %s:%d\n", file, line);
|
19
|
+
fprintf(stderr, "RNG seed was %u\n", rng_seed);
|
20
|
+
abort();
|
21
|
+
}
|
22
|
+
|
23
|
+
#define ASSERT(expr) if (!(expr)) assertion_failed(__FILE__, __LINE__);
|
24
|
+
|
25
|
+
typedef u32 (*cksum_fn_t)(u32, const void *, size_t);
|
26
|
+
|
27
|
+
static u32
|
28
|
+
zlib_adler32(u32 adler, const void *buf, size_t len)
|
29
|
+
{
|
30
|
+
return adler32(adler, buf, len);
|
31
|
+
}
|
32
|
+
|
33
|
+
static u32
|
34
|
+
zlib_crc32(u32 crc, const void *buf, size_t len)
|
35
|
+
{
|
36
|
+
return crc32(crc, buf, len);
|
37
|
+
}
|
38
|
+
|
39
|
+
static u32
|
40
|
+
select_initial_crc(void)
|
41
|
+
{
|
42
|
+
if (rand() & 1)
|
43
|
+
return 0;
|
44
|
+
return ((u32)rand() << 16) | rand();
|
45
|
+
}
|
46
|
+
|
47
|
+
static u32
|
48
|
+
select_initial_adler(void)
|
49
|
+
{
|
50
|
+
if (rand() & 1)
|
51
|
+
return 1;
|
52
|
+
return ((u32)(rand() % 65521) << 16) | (rand() % 65521);
|
53
|
+
}
|
54
|
+
|
55
|
+
static void
|
56
|
+
test_initial_values(cksum_fn_t cksum, u32 expected)
|
57
|
+
{
|
58
|
+
ASSERT(cksum(0, NULL, 0) == expected);
|
59
|
+
if (cksum != zlib_adler32) /* broken */
|
60
|
+
ASSERT(cksum(0, NULL, 1) == expected);
|
61
|
+
ASSERT(cksum(0, NULL, 1234) == expected);
|
62
|
+
ASSERT(cksum(1234, NULL, 0) == expected);
|
63
|
+
ASSERT(cksum(1234, NULL, 1234) == expected);
|
64
|
+
}
|
65
|
+
|
66
|
+
static void
|
67
|
+
test_multipart(const u8 *buffer, unsigned size, const char *name,
|
68
|
+
cksum_fn_t cksum, u32 v, u32 expected)
|
69
|
+
{
|
70
|
+
unsigned division = (size != 0) ? rand() % size : 0;
|
71
|
+
v = cksum(v, buffer, division);
|
72
|
+
v = cksum(v, buffer + division, size - division);
|
73
|
+
if (v != expected) {
|
74
|
+
fprintf(stderr, "%s checksum failed multipart test\n", name);
|
75
|
+
ASSERT(0);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
static void
|
80
|
+
test_checksums(const void *buffer, unsigned size, const char *name,
|
81
|
+
cksum_fn_t cksum1, cksum_fn_t cksum2, u32 initial_value)
|
82
|
+
{
|
83
|
+
u32 v1 = cksum1(initial_value, buffer, size);
|
84
|
+
u32 v2 = cksum2(initial_value, buffer, size);
|
85
|
+
|
86
|
+
if (v1 != v2) {
|
87
|
+
fprintf(stderr, "%s checksum mismatch\n", name);
|
88
|
+
fprintf(stderr, "initial_value=0x%08"PRIx32", buffer=%p, "
|
89
|
+
"contents ", initial_value, buffer);
|
90
|
+
for (unsigned i = 0; i < size; i++)
|
91
|
+
fprintf(stderr, "%02x", ((const u8 *)buffer)[i]);
|
92
|
+
fprintf(stderr, "\n");
|
93
|
+
ASSERT(0);
|
94
|
+
}
|
95
|
+
|
96
|
+
if ((rand() & 15) == 0) {
|
97
|
+
test_multipart(buffer, size, name, cksum1, initial_value, v1);
|
98
|
+
test_multipart(buffer, size, name, cksum2, initial_value, v1);
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
int
|
103
|
+
tmain(int argc, tchar *argv[])
|
104
|
+
{
|
105
|
+
u8 buffer[256];
|
106
|
+
|
107
|
+
rng_seed = time(NULL);
|
108
|
+
srand(rng_seed);
|
109
|
+
|
110
|
+
test_initial_values(libdeflate_adler32, 1);
|
111
|
+
test_initial_values(zlib_adler32, 1);
|
112
|
+
test_initial_values(libdeflate_crc32, 0);
|
113
|
+
test_initial_values(zlib_crc32, 0);
|
114
|
+
|
115
|
+
for (uint32_t i = 0; i < 50000; i++) {
|
116
|
+
/* test different buffer sizes and alignments */
|
117
|
+
int start = rand() % sizeof(buffer);
|
118
|
+
int len = rand() % (sizeof(buffer) - start);
|
119
|
+
|
120
|
+
for (int i = start; i < start + len; i++)
|
121
|
+
buffer[i] = rand();
|
122
|
+
|
123
|
+
test_checksums(&buffer[start], len, "Adler-32",
|
124
|
+
libdeflate_adler32, zlib_adler32,
|
125
|
+
select_initial_adler());
|
126
|
+
|
127
|
+
test_checksums(&buffer[start], len, "CRC-32",
|
128
|
+
libdeflate_crc32, zlib_crc32,
|
129
|
+
select_initial_crc());
|
130
|
+
}
|
131
|
+
|
132
|
+
printf("Adler-32 and CRC-32 checksum tests passed!\n");
|
133
|
+
|
134
|
+
return 0;
|
135
|
+
}
|
@@ -0,0 +1,118 @@
|
|
1
|
+
/*
|
2
|
+
* tgetopt.c - portable replacement for GNU getopt()
|
3
|
+
*
|
4
|
+
* Copyright 2016 Eric Biggers
|
5
|
+
*
|
6
|
+
* Permission is hereby granted, free of charge, to any person
|
7
|
+
* obtaining a copy of this software and associated documentation
|
8
|
+
* files (the "Software"), to deal in the Software without
|
9
|
+
* restriction, including without limitation the rights to use,
|
10
|
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
* copies of the Software, and to permit persons to whom the
|
12
|
+
* Software is furnished to do so, subject to the following
|
13
|
+
* conditions:
|
14
|
+
*
|
15
|
+
* The above copyright notice and this permission notice shall be
|
16
|
+
* included in all copies or substantial portions of the Software.
|
17
|
+
*
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20
|
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22
|
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23
|
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24
|
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25
|
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26
|
+
*/
|
27
|
+
|
28
|
+
#include "prog_util.h"
|
29
|
+
|
30
|
+
tchar *toptarg;
|
31
|
+
int toptind = 1, topterr = 1, toptopt;
|
32
|
+
|
33
|
+
/*
|
34
|
+
* This is a simple implementation of getopt(). It can be compiled with either
|
35
|
+
* 'char' or 'wchar_t' as the character type.
|
36
|
+
*
|
37
|
+
* Do *not* use this implementation if you need any of the following features,
|
38
|
+
* as they are not supported:
|
39
|
+
* - Long options
|
40
|
+
* - Option-related arguments retained in argv, not nulled out
|
41
|
+
* - '+' and '-' characters in optstring
|
42
|
+
*/
|
43
|
+
int
|
44
|
+
tgetopt(int argc, tchar *argv[], const tchar *optstring)
|
45
|
+
{
|
46
|
+
static tchar empty[1];
|
47
|
+
static tchar *nextchar;
|
48
|
+
static bool done;
|
49
|
+
|
50
|
+
if (toptind == 1) {
|
51
|
+
/* Starting to scan a new argument vector */
|
52
|
+
nextchar = NULL;
|
53
|
+
done = false;
|
54
|
+
}
|
55
|
+
|
56
|
+
while (!done && (nextchar != NULL || toptind < argc)) {
|
57
|
+
if (nextchar == NULL) {
|
58
|
+
/* Scanning a new argument */
|
59
|
+
tchar *arg = argv[toptind++];
|
60
|
+
if (arg[0] == '-' && arg[1] != '\0') {
|
61
|
+
if (arg[1] == '-' && arg[2] == '\0') {
|
62
|
+
/* All args after "--" are nonoptions */
|
63
|
+
argv[toptind - 1] = NULL;
|
64
|
+
done = true;
|
65
|
+
} else {
|
66
|
+
/* Start of short option characters */
|
67
|
+
nextchar = &arg[1];
|
68
|
+
}
|
69
|
+
}
|
70
|
+
} else {
|
71
|
+
/* More short options in previous arg */
|
72
|
+
tchar opt = *nextchar;
|
73
|
+
tchar *p = tstrchr(optstring, opt);
|
74
|
+
if (p == NULL) {
|
75
|
+
if (topterr)
|
76
|
+
msg("invalid option -- '%"TC"'", opt);
|
77
|
+
toptopt = opt;
|
78
|
+
return '?';
|
79
|
+
}
|
80
|
+
/* 'opt' is a valid short option character */
|
81
|
+
nextchar++;
|
82
|
+
toptarg = NULL;
|
83
|
+
if (*(p + 1) == ':') {
|
84
|
+
/* 'opt' can take an argument */
|
85
|
+
if (*nextchar != '\0') {
|
86
|
+
/* Optarg is in same argv argument */
|
87
|
+
toptarg = nextchar;
|
88
|
+
nextchar = empty;
|
89
|
+
} else if (toptind < argc && *(p + 2) != ':') {
|
90
|
+
/* Optarg is next argv argument */
|
91
|
+
argv[toptind - 1] = NULL;
|
92
|
+
toptarg = argv[toptind++];
|
93
|
+
} else if (*(p + 2) != ':') {
|
94
|
+
if (topterr && *optstring != ':') {
|
95
|
+
msg("option requires an "
|
96
|
+
"argument -- '%"TC"'", opt);
|
97
|
+
}
|
98
|
+
toptopt = opt;
|
99
|
+
opt = (*optstring == ':') ? ':' : '?';
|
100
|
+
}
|
101
|
+
}
|
102
|
+
if (*nextchar == '\0') {
|
103
|
+
argv[toptind - 1] = NULL;
|
104
|
+
nextchar = NULL;
|
105
|
+
}
|
106
|
+
return opt;
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
/* Done scanning. Move all nonoptions to the end, set optind to the
|
111
|
+
* index of the first nonoption, and return -1. */
|
112
|
+
toptind = argc;
|
113
|
+
while (--argc > 0)
|
114
|
+
if (argv[argc] != NULL)
|
115
|
+
argv[--toptind] = argv[argc];
|
116
|
+
done = true;
|
117
|
+
return -1;
|
118
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#include <assert.h>
|
2
|
+
#include <libdeflate.h>
|
3
|
+
#include <string.h>
|
4
|
+
#include <fcntl.h>
|
5
|
+
#include <unistd.h>
|
6
|
+
#include <sys/stat.h>
|
7
|
+
|
8
|
+
int main(int argc, char **argv)
|
9
|
+
{
|
10
|
+
struct libdeflate_decompressor *d;
|
11
|
+
struct libdeflate_compressor *c;
|
12
|
+
int ret;
|
13
|
+
int fd = open(argv[1], O_RDONLY);
|
14
|
+
struct stat stbuf;
|
15
|
+
assert(fd >= 0);
|
16
|
+
ret = fstat(fd, &stbuf);
|
17
|
+
assert(!ret);
|
18
|
+
|
19
|
+
char in[stbuf.st_size];
|
20
|
+
ret = read(fd, in, sizeof in);
|
21
|
+
assert(ret == sizeof in);
|
22
|
+
|
23
|
+
c = libdeflate_alloc_compressor(6);
|
24
|
+
d = libdeflate_alloc_decompressor();
|
25
|
+
|
26
|
+
char out[sizeof(in)];
|
27
|
+
char checkarray[sizeof(in)];
|
28
|
+
|
29
|
+
size_t csize = libdeflate_deflate_compress(c, in,sizeof in, out, sizeof out);
|
30
|
+
if (csize) {
|
31
|
+
enum libdeflate_result res;
|
32
|
+
res = libdeflate_deflate_decompress(d, out, csize, checkarray, sizeof in, NULL);
|
33
|
+
assert(!res);
|
34
|
+
assert(!memcmp(in, checkarray, sizeof in));
|
35
|
+
}
|
36
|
+
|
37
|
+
libdeflate_free_compressor(c);
|
38
|
+
libdeflate_free_decompressor(d);
|
39
|
+
return 0;
|
40
|
+
}
|