Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/codexlib/bzip/bzip.c
1810 views
1
#pragma prototyped
2
3
/*
4
* bzip encoder/decoder
5
*/
6
7
#include <codex.h>
8
#include <bzlib.h>
9
#include <ctype.h>
10
11
#define MINLEVEL 1
12
#define MAXLEVEL 9
13
14
#define X(x) #x
15
#define S(x) X(x)
16
17
typedef struct State_s
18
{
19
Codex_t* codex;
20
BZFILE* bz;
21
int level;
22
} State_t;
23
24
static int
25
bzip_ident(Codexmeth_t* meth, const void* head, size_t headsize, char* name, size_t namesize)
26
{
27
unsigned char* h = (unsigned char*)head;
28
29
if (headsize >= 4 && h[0] == 'B' && h[1] == 'Z' && h[2] == 'h' && (h[3] >= '0' && h[3] <= '9'))
30
{
31
strncopy(name, meth->name, namesize);
32
return 1;
33
}
34
return 0;
35
}
36
37
static int
38
bzip_open(Codex_t* p, char* const args[], Codexnum_t flags)
39
{
40
register State_t* state;
41
const char* s;
42
char* e;
43
int i;
44
int v;
45
int level = MAXLEVEL;
46
47
i = 2;
48
while (s = args[i++])
49
{
50
if (isdigit(*s))
51
v = strton(s, &e, NiL, 0);
52
else
53
{
54
e = (char*)s;
55
if (e[0] == 'n' && e[1] == 'o')
56
{
57
e += 2;
58
v = 0;
59
}
60
else
61
v = 1;
62
}
63
if (!*e)
64
{
65
if (v < MINLEVEL || v > MAXLEVEL)
66
{
67
if (p->disc->errorf)
68
(*p->disc->errorf)(NiL, p->disc, 2, "%s: compression level must be in [%d..%d]", s, MINLEVEL, MAXLEVEL);
69
return -1;
70
}
71
level = v;
72
}
73
else
74
{
75
if (p->disc->errorf)
76
(*p->disc->errorf)(NiL, p->disc, 2, "%s: unknown option", s);
77
return -1;
78
}
79
}
80
if (!(p->op = sfopen(NiL, "/dev/null", (p->flags & CODEX_DECODE) ? "r" : "w")))
81
{
82
if (p->disc->errorf)
83
(*p->disc->errorf)(NiL, p->disc, 2, "cannot swap main stream");
84
return -1;
85
}
86
sfswap(p->op, p->sp);
87
if (!(state = newof(0, State_t, 1, 0)))
88
{
89
if (p->disc->errorf)
90
(*p->disc->errorf)(NiL, p->disc, 2, "out of space");
91
return -1;
92
}
93
state->codex = p;
94
state->level = level;
95
p->data = state;
96
return 0;
97
}
98
99
static int
100
bzip_init(Codex_t* p)
101
{
102
State_t* state = (State_t*)p->data;
103
char* m;
104
char mode[8];
105
106
m = mode;
107
if (p->flags & CODEX_ENCODE)
108
*m++ = 'w';
109
else
110
*m++ = 'r';
111
*m++ = 'b';
112
*m++ = 'o';
113
*m++ = '0' + state->level;
114
*m = 0;
115
return (state->bz = bzfopen(p->op, mode)) ? 0 : -1;
116
}
117
118
static int
119
bzip_done(Codex_t* p)
120
{
121
State_t* state = (State_t*)p->data;
122
int r;
123
124
r = bzclose(state->bz) ? -1 : 0;
125
free(state);
126
return r;
127
}
128
129
static ssize_t
130
bzip_read(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* dp)
131
{
132
return bzread(((State_t*)CODEX(dp)->data)->bz, buf, n);
133
}
134
135
static ssize_t
136
bzip_write(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* dp)
137
{
138
return bzwrite(((State_t*)CODEX(dp)->data)->bz, buf, n);
139
}
140
141
Codexmeth_t codex_bzip =
142
{
143
"bzip",
144
"bzip2 compression. The first parameter is the compression level,"
145
" " S(MINLEVEL) ":least, " S(MAXLEVEL) ":most(default).",
146
0,
147
CODEX_DECODE|CODEX_ENCODE|CODEX_COMPRESS,
148
0,
149
bzip_ident,
150
bzip_open,
151
0,
152
bzip_init,
153
bzip_done,
154
bzip_read,
155
bzip_write,
156
0,
157
0,
158
0,
159
0,
160
0,
161
CODEXNEXT(bzip)
162
};
163
164
CODEXLIB(bzip)
165
166