Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libpz/pzread.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
#include "pzlib.h"
23
24
/*
25
* read a buffer from a pz stream
26
* this code mirrors pzinflate()
27
*/
28
29
ssize_t
30
pzread(register Pz_t* pz, void* buf, size_t z)
31
{
32
register Pzpart_t* pp;
33
register int i;
34
register int j;
35
register int k;
36
register size_t m;
37
ssize_t n;
38
ssize_t w;
39
size_t r;
40
unsigned char* ob;
41
unsigned char* om;
42
unsigned char* x;
43
Pzwrite_f writef;
44
45
pp = pz->part;
46
if (z >= pp->row)
47
n = (z / pp->row) * pp->row;
48
else if (!(pz->flags & PZ_FORCE))
49
return -1;
50
else
51
n = z;
52
if (writef = pz->disc->writef)
53
{
54
if (sfstrbuf(pz->str, buf, z, 0))
55
{
56
if (pz->disc->errorf)
57
(*pz->disc->errorf)(pz, pz->disc, 2, "cannot initailize tmp stream");
58
return -1;
59
}
60
if (!pz->wrk && !(pz->wrk = vmnewof(pz->vm, 0, unsigned char, pz->mrow, 0)))
61
return -1;
62
ob = pz->wrk;
63
w = -1;
64
}
65
else
66
{
67
ob = (unsigned char*)buf;
68
om = ob + n;
69
}
70
if (pz->flags & PZ_FORCE)
71
{
72
if (writef)
73
{
74
m = pz->part->row;
75
if (!(ob = (unsigned char*)sfreserve(pz->io, m, 0)))
76
{
77
if (sfvalue(pz->io))
78
{
79
if (pz->disc->errorf)
80
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: data corrupted", pz->path);
81
return -1;
82
}
83
return 0;
84
}
85
if ((n = (*writef)(pz, pz->str, ob, pz->disc)) <= 0)
86
return -1;
87
if (z < n)
88
return -1;
89
w = (z / n) * n;
90
while ((w -= n) > 0)
91
{
92
if (!(ob = (unsigned char*)sfreserve(pz->io, m, 0)))
93
{
94
if (sfvalue(pz->io))
95
{
96
if (pz->disc->errorf)
97
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: data corrupted", pz->path);
98
return -1;
99
}
100
break;
101
}
102
if ((n = (*writef)(pz, pz->str, ob, pz->disc)) <= 0)
103
return -1;
104
}
105
return (ssize_t)sfstrtell(pz->str);
106
}
107
else
108
return sfread(pz->io, buf, n);
109
}
110
if (pz->prefix.count)
111
{
112
if (pz->prefix.data)
113
{
114
if (z < (m = pz->prefix.count))
115
m = z;
116
memcpy(buf, pz->prefix.data, m);
117
pz->prefix.count -= m;
118
pz->prefix.data += m;
119
return m;
120
}
121
pz->prefix.count = 0;
122
}
123
for (;;)
124
{
125
if (!pz->rs.hi)
126
{
127
if (pz->rs.lo)
128
return 0;
129
if (!(m = sfgetu(pz->io)))
130
{
131
if ((k = sfgetc(pz->io)) == PZ_MARK_PART)
132
{
133
if ((m = sfgetu(pz->io)) && !sferror(pz->io) && !sfeof(pz->io) && (x = (unsigned char*)sfreserve(pz->io, m, 0)))
134
{
135
r = om - ob;
136
if (m > r)
137
{
138
sfungetc(pz->io, 0);
139
memcpy(ob, x, r);
140
pz->prefix.count = m - r;
141
pz->prefix.data = (char*)x + r;
142
return z;
143
}
144
memcpy(ob, x, m);
145
ob += m;
146
}
147
}
148
else if (k != -1)
149
sfungetc(pz->io, k);
150
switch (pzfile(pz))
151
{
152
case 0:
153
pz->rs.lo = 1;
154
goto done;
155
case 1:
156
continue;
157
default:
158
return -1;
159
}
160
}
161
if (pp->nmap)
162
{
163
if (m > pz->win || (m % pp->nmap) || sfread(pz->io, pz->buf, m) != m)
164
{
165
if (pz->disc->errorf)
166
(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: data corrupted", pz->path);
167
return -1;
168
}
169
n = m / pp->nmap;
170
m = 0;
171
j = 0;
172
k = 0;
173
for (i = 0; i < pp->nmap; i++)
174
{
175
if (i > 0 && pp->lab[i] == pp->lab[i - 1])
176
j++;
177
else
178
j = m;
179
if (!pp->value || pp->value[i] < 0)
180
pp->mix[k++] = pz->buf + j;
181
m += n;
182
}
183
}
184
else if (m != 1)
185
{
186
if (pz->disc->errorf)
187
(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: data corrupted", pz->path);
188
return -1;
189
}
190
m = sfgetu(pz->io);
191
if (m < pp->row || sfread(pz->io, pz->pat, pp->row) != pp->row)
192
{
193
if (pz->disc->errorf)
194
(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: data corrupted", pz->path);
195
return -1;
196
}
197
m -= pp->row;
198
if (sfread(pz->io, pz->nxt = pz->val, m) != m)
199
{
200
if (pz->disc->errorf)
201
(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: data corrupted", pz->path);
202
return -1;
203
}
204
pz->rs.hi = k;
205
PZGETZ(pz, pz->io, pz->rs.lo, i);
206
}
207
for (;;)
208
{
209
while (pz->rs.lo > 0)
210
{
211
pz->rs.lo--;
212
memcpy(ob, pz->pat, pp->row);
213
for (i = 0; i < pz->rs.hi; i++)
214
{
215
ob[pp->map[i]] = *pp->mix[i];
216
pp->mix[i] += pp->inc[i];
217
}
218
if (writef)
219
{
220
if ((n = (*writef)(pz, pz->str, ob, pz->disc)) <= 0)
221
return -1;
222
if (w < 0)
223
w = (z / n) * (n - 1);
224
if ((w -= n) <= 0)
225
goto done;
226
}
227
else if ((ob += pp->row) >= om)
228
goto done;
229
}
230
PZGETP(pz, pz->io, m, i, break);
231
for (;;)
232
{
233
pz->pat[m - 1] = *pz->nxt++;
234
PZGETP(pz, pz->io, m, i, break);
235
}
236
PZGETZ(pz, pz->io, pz->rs.lo, i);
237
}
238
pz->rs.hi = 0;
239
}
240
done:
241
return writef ? (ssize_t)sfstrtell(pz->str) : (ob - (unsigned char*)buf);
242
}
243
244