Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libbz/sfdcbzip.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the zlib package *
4
* Copyright (c) 1996-2003 Jean-loup Gailly and Mark Adler *
5
* *
6
* This software is provided 'as-is', without any express or implied *
7
* warranty. In no event will the authors be held liable for any *
8
* damages arising from the use of this software. *
9
* *
10
* Permission is granted to anyone to use this software for any *
11
* purpose, including commercial applications, and to alter it and *
12
* redistribute it freely, subject to the following restrictions: *
13
* *
14
* 1. The origin of this software must not be misrepresented; *
15
* you must not claim that you wrote the original software. If *
16
* you use this software in a product, an acknowledgment in the *
17
* product documentation would be appreciated but is not *
18
* required. *
19
* *
20
* 2. Altered source versions must be plainly marked as such, *
21
* and must not be misrepresented as being the original *
22
* software. *
23
* *
24
* 3. This notice may not be removed or altered from any source *
25
* distribution. *
26
* *
27
* This software is provided "as-is", without any express or implied *
28
* warranty. In no event will the authors be held liable for any damages*
29
* arising from the use of this software. *
30
* *
31
* Permission is granted to anyone to use this software for any purpose,*
32
* including commercial applications, and to alter it and redistribute i*
33
* freely, subject to the following restrictions: *
34
* *
35
* 1. The origin of this software must not be misrepresented; you must n*
36
* claim that you wrote the original software. If you use this softwa*
37
* in a product, an acknowledgment in the product documentation would*
38
* be appreciated but is not required. *
39
* *
40
* 2. Altered source versions must be plainly marked as such, and must n*
41
* be misrepresented as being the original software. *
42
* *
43
* 3. This notice may not be removed or altered from any source *
44
* distribution. *
45
* *
46
* Julian R Seward *
47
* *
48
***********************************************************************/
49
#pragma prototyped
50
51
/*
52
* sfio bzip discipline
53
*/
54
55
#include <sfio_t.h>
56
#include <ast.h>
57
#include <bzlib.h>
58
#include <sfdcbzip.h>
59
60
#define bzsync(p,o) (-1)
61
62
typedef struct
63
{
64
Sfdisc_t disc; /* sfio discipline */
65
Bz_t* bz; /* bz handle */
66
} Sfbzip_t;
67
68
/*
69
* bzip exception handler
70
* free on close
71
*/
72
73
static int
74
sfbzexcept(Sfio_t* sp, int op, void* val, Sfdisc_t* dp)
75
{
76
register Sfbzip_t* bz = (Sfbzip_t*)dp;
77
int r;
78
79
NoP(sp);
80
#if 1
81
{
82
static char aha[] = "AHA sfdcbzip event 0\n";
83
static int init;
84
85
if (!init)
86
init = getenv("SFBZ_DEBUG") ? 1 : -1;
87
if (init > 0)
88
{
89
aha[sizeof(aha) - 3] = '0' + op;
90
write(2, aha, sizeof(aha) - 1);
91
}
92
}
93
#endif
94
switch (op)
95
{
96
case SF_ATEXIT:
97
sfdisc(sp, SF_POPDISC);
98
return 0;
99
case SF_CLOSING:
100
case SF_DPOP:
101
case SF_FINAL:
102
if (bz->bz)
103
{
104
r = bzclose(bz->bz) ? -1 : 0;
105
bz->bz = 0;
106
}
107
else
108
r = 0;
109
if (op != SF_CLOSING)
110
free(dp);
111
return r;
112
case SF_DBUFFER:
113
return 1;
114
case SF_READ:
115
case SF_WRITE:
116
return *((ssize_t*)val) < 0 ? -1 : 0;
117
case SF_SYNC:
118
return val ? 0 : bzflush(bz->bz);
119
case SFBZ_HANDLE:
120
return (*((Bz_t**)val) = bz->bz) ? 1 : -1;
121
case SFBZ_GETPOS:
122
return (*((Sfoff_t*)val) = bzsync(bz->bz, (z_off_t)(-1))) == -1 ? -1 : 0;
123
case SFBZ_SETPOS:
124
return bzsync(bz->bz, (z_off_t)(*((Sfoff_t*)val))) == -1 ? -1 : 0;
125
}
126
return 0;
127
}
128
129
/*
130
* sfio bzip discipline read
131
*/
132
133
static ssize_t
134
sfbzread(Sfio_t* fp, Void_t* buf, size_t size, Sfdisc_t* dp)
135
{
136
register Sfbzip_t* bz = (Sfbzip_t*)dp;
137
138
return bzread(bz->bz, buf, size);
139
}
140
141
/*
142
* sfio bzip discipline write
143
*/
144
145
static ssize_t
146
sfbzwrite(Sfio_t* fp, const Void_t* buf, size_t size, Sfdisc_t* dp)
147
{
148
register Sfbzip_t* bz = (Sfbzip_t*)dp;
149
150
return (bzwrite(bz->bz, (void*)buf, size) < 0) ? -1 : size;
151
}
152
153
/*
154
* create and push the sfio bzip discipline
155
*
156
* (flags&SFBZ_VERIFY) return
157
* >0 is a bzip file
158
* 0 not a bzip file
159
* <0 error
160
* otherwise return
161
* >0 discipline pushed
162
* 0 discipline not needed
163
* <0 error
164
*/
165
166
int
167
sfdcbzip(Sfio_t* sp, int flags)
168
{
169
char* m;
170
Sfbzip_t* bz;
171
char mode[10];
172
173
if (sfset(sp, 0, 0) & SF_READ)
174
{
175
register unsigned char* s;
176
register int n;
177
178
/*
179
* peek the first 4 bytes to verify the magic
180
*
181
* BZh[0-9] sfdcbzip bzip
182
*/
183
184
if (!(n = sfset(sp, 0, 0) & SF_SHARE))
185
sfset(sp, SF_SHARE, 1);
186
s = (unsigned char*)sfreserve(sp, 4, 1);
187
if (!n)
188
sfset(sp, SF_SHARE, 0);
189
if (!s)
190
return -1;
191
n = s[0] == 'B' && s[1] == 'Z' && s[2] == 'h' && (s[3] >= '0' && s[3] <= '9');
192
sfread(sp, s, 0);
193
if (!n || (flags & SFBZ_VERIFY))
194
return n;
195
}
196
else if (flags & SFBZ_VERIFY)
197
return -1;
198
if (!(bz = newof(0, Sfbzip_t, 1, 0)))
199
return -1;
200
bz->disc.exceptf = sfbzexcept;
201
if (sfset(sp, 0, 0) & SF_READ)
202
bz->disc.readf = sfbzread;
203
else
204
bz->disc.writef = sfbzwrite;
205
m = mode;
206
*m++ = (sfset(sp, 0, 0) & SF_READ) ? 'r' : 'w';
207
*m++ = 'o';
208
if ((flags &= 0xf) > 0 && flags <= 9)
209
*m++ = '0' + flags;
210
*m = 0;
211
if (sfdisc(sp, &bz->disc) != &bz->disc || !(bz->bz = bzdopen(sffileno(sp), mode)))
212
{
213
free(bz);
214
return -1;
215
}
216
sfsetbuf(sp, NiL, SF_BUFSIZE);
217
if (!(sfset(sp, 0, 0) & SF_READ))
218
sfset(sp, SF_IOCHECK, 1);
219
return 1;
220
}
221
222