Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/pzip/pcmp.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1998-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
22
/*
23
* Glenn Fowler
24
* AT&T Research
25
*/
26
27
static const char id[] = "\n@(#)$Id: pcmp (AT&T Research) 1998-11-01 $\0\n";
28
29
#include <ast.h>
30
#include <ctype.h>
31
#include <error.h>
32
#include <ls.h>
33
#include <pzip.h>
34
#include <zlib.h>
35
36
static struct
37
{
38
int test;
39
int level;
40
int verbose;
41
} state;
42
43
/*
44
* return the compressed size of buffer f of fsize bytes
45
*/
46
47
static size_t
48
zip(unsigned char* f, size_t fsize, unsigned char* t, size_t tsize)
49
{
50
unsigned long used;
51
52
used = tsize;
53
if (compress2(t, &used, f, fsize, state.level) != Z_OK)
54
error(3, "gzip compress failed");
55
return used;
56
}
57
58
/*
59
* return the difference size of buffer f of fsize bytes
60
*/
61
62
static size_t
63
dif(unsigned char* f, size_t fsize, unsigned char* t, size_t tsize, size_t cols)
64
{
65
unsigned char* p;
66
unsigned char* e;
67
size_t n;
68
size_t i;
69
70
static Sfio_t* dp;
71
static Sfio_t* vp;
72
73
if (!dp && !(dp = sfstropen()) || !vp && !(vp = sfstropen()))
74
error(ERROR_SYSTEM|3, "out of space [tmp streams]");
75
p = (unsigned char*)memcpy(t, f, cols);
76
sfwrite(dp, p, cols);
77
n = 1;
78
for (e = f + fsize; f < e; f += cols)
79
{
80
for (i = 0; i < cols; i++)
81
if (p[i] != f[i])
82
{
83
sfputu(dp, n);
84
sfputu(dp, i + 1);
85
sfputc(vp, p[i] = f[i]);
86
n = 0;
87
while (++i < cols)
88
if (p[i] != f[i])
89
{
90
sfputu(dp, i + 1);
91
sfputc(vp, p[i] = f[i]);
92
}
93
sfputu(dp, 0);
94
break;
95
}
96
n++;
97
}
98
sfputu(dp, n);
99
sfputu(dp, 0);
100
fsize = sfstrtell(vp);
101
sfputu(dp, fsize);
102
sfwrite(dp, sfstrseek(vp, 0, SEEK_SET), fsize);
103
fsize = sfstrtell(dp);
104
return zip((unsigned char*)sfstrseek(dp, 0, SEEK_SET), fsize, t, tsize);
105
}
106
107
main(int argc, char** argv)
108
{
109
size_t cols;
110
size_t rows;
111
size_t pct;
112
size_t z;
113
size_t d;
114
size_t n;
115
size_t i;
116
unsigned int h;
117
unsigned int m;
118
size_t datsize;
119
size_t bufsize;
120
unsigned char* dat;
121
unsigned char* buf;
122
unsigned char* end;
123
unsigned char* s;
124
unsigned char* p;
125
126
error_info.id = "pcmp";
127
state.level = 6;
128
cols = 100;
129
rows = 1000;
130
for (;;)
131
{
132
switch (optget(argv, "c#[cols]l#[compression-level]r#[rows]vT#[test-mask]"))
133
{
134
case 'c':
135
cols = opt_info.num;
136
continue;
137
case 'l':
138
state.level = opt_info.num;
139
continue;
140
case 'p':
141
pct = opt_info.num;
142
continue;
143
case 'r':
144
rows = opt_info.num;
145
continue;
146
case 'v':
147
state.verbose = 1;
148
continue;
149
case 'T':
150
state.test |= opt_info.num;
151
continue;
152
case '?':
153
error(ERROR_USAGE|4, "%s", opt_info.arg);
154
continue;
155
case ':':
156
error(2, "%s", opt_info.arg);
157
continue;
158
}
159
break;
160
}
161
argv += opt_info.index;
162
if (error_info.errors || *argv)
163
error(ERROR_USAGE|4, "%s", optusage(NiL));
164
165
/*
166
* set up the workspace
167
*/
168
169
datsize = rows * cols;
170
if (!(dat = newof(0, unsigned char, datsize, 0)))
171
error(ERROR_SYSTEM|3, "out of space [dat]");
172
bufsize = 4 * datsize;
173
if (!(buf = newof(0, unsigned char, bufsize, 0)))
174
error(ERROR_SYSTEM|3, "out of space [buf]");
175
end = dat + datsize;
176
177
/*
178
* loop over the probabilities
179
*/
180
181
h = (unsigned int)time(NiL) ^ (unsigned int)getpid();
182
for (n = 0; n < 100; n++)
183
{
184
m = (UINT_MAX / 100) * n;
185
memset(dat, 040, cols);
186
for (s = p = dat; s < end; p = s, s += cols)
187
for (i = 0; i < cols; i++)
188
if ((h = h * 0x63c63cd9L + 0x9c39c33dL) < m)
189
s[i] = 040 | (h & 0177);
190
else
191
s[i] = p[i];
192
d = dif(dat, datsize, buf, bufsize, cols);
193
z = zip(dat, datsize, buf, bufsize);
194
sfprintf(sfstdout, "%2d %5u %5u\n", n, d, z);
195
if (d > z)
196
break;
197
}
198
return 0;
199
}
200
201