Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libpz/pzwrite.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
* write a buffer to a pz stream
26
*
27
* code cannibalized from pzdeflate()
28
* the PZ_SORT pzsync() code could be more efficient
29
*/
30
31
ssize_t
32
pzwrite(register Pz_t* pz, Sfio_t* op, const void* buf, size_t n)
33
{
34
register int i;
35
register int j;
36
register unsigned char* bp;
37
register Pzpart_t* pp;
38
register unsigned char* pat;
39
register unsigned char* low;
40
Pzelt_t* elt;
41
unsigned char* be;
42
size_t k;
43
size_t x;
44
ssize_t r;
45
Sfio_t* tmp;
46
47
if (!(pz->flags & PZ_WRITE))
48
{
49
if (pz->disc->errorf)
50
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot deflate -- not open for write", pz->path);
51
return -1;
52
}
53
if (!n)
54
return 0;
55
if (pzheadwrite(pz, op))
56
return -1;
57
if (pz->flags & PZ_NOPZIP)
58
{
59
if ((r = sfwrite(op, buf, n)) < 0)
60
{
61
if (pz->disc->errorf)
62
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: write error", pz->path);
63
return -1;
64
}
65
return r;
66
}
67
pp = pz->part;
68
if (pz->flags & PZ_SORT)
69
{
70
pz->ws.bp = pz->buf;
71
if (!pz->sort.order)
72
{
73
k = sizeof(Dtlink_t) + roundof(pp->row, sizeof(Dtlink_t));
74
pz->sort.freedisc.link = offsetof(Pzelt_t, link);
75
pz->sort.orderdisc.link = offsetof(Pzelt_t, link);
76
pz->sort.orderdisc.key = offsetof(Pzelt_t, buf);
77
pz->sort.orderdisc.size = pp->row;
78
if (!(elt = (Pzelt_t*)vmnewof(pz->vm, 0, char, pp->col * k, 0)) || !(pz->sort.order = dtnew(pz->vm, &pz->sort.orderdisc, Dtobag)) || !(pz->sort.free = dtnew(pz->vm, &pz->sort.freedisc, Dtlist)))
79
return pznospace(pz);
80
for (i = 0; i < pp->col; i++)
81
{
82
dtinsert(pz->sort.free, elt);
83
elt = (Pzelt_t*)((char*)elt + k);
84
}
85
}
86
bp = (unsigned char*)buf;
87
k = n;
88
if (pz->ws.sz)
89
{
90
x = pz->ws.sz;
91
if (x > n)
92
x = n;
93
memcpy(pz->ws.sp, bp, x);
94
bp += x;
95
k -= x;
96
if (pz->ws.sz -= x)
97
pz->ws.sp += x;
98
else
99
dtinsert(pz->sort.order, pz->ws.se);
100
}
101
x = pp->row;
102
while (k > 0)
103
{
104
while (!(elt = (Pzelt_t*)dtfirst(pz->sort.free)))
105
if (pzsync(pz))
106
return -1;
107
dtdelete(pz->sort.free, elt);
108
if (k < x)
109
{
110
memcpy(elt->buf, bp, k);
111
pz->ws.sp = elt->buf + k;
112
pz->ws.sz = x - k;
113
pz->ws.se = elt;
114
break;
115
}
116
memcpy(elt->buf, bp, x);
117
dtinsert(pz->sort.order, elt);
118
bp += x;
119
k -= x;
120
}
121
return n;
122
}
123
if (pz->ws.pc || n < pp->row)
124
{
125
if (!pz->ws.pb && !(pz->ws.pb = vmnewof(pz->vm, 0, unsigned char, pp->row, 0)))
126
return -1;
127
x = pp->row - pz->ws.pc;
128
if (x > n)
129
x = n;
130
memcpy(pz->ws.pb + pz->ws.pc, buf, x);
131
if ((pz->ws.pc += x) < pp->row)
132
return x;
133
pz->ws.pc = 0;
134
if (pzwrite(pz, op, pz->ws.pb, pp->row) != pp->row)
135
return -1;
136
if (!(n -= x))
137
return x;
138
}
139
else
140
x = 0;
141
bp = (unsigned char*)buf + x;
142
be = bp + n;
143
if (k = n % pp->row)
144
{
145
if (!pz->ws.pb && !(pz->ws.pb = vmnewof(pz->vm, 0, unsigned char, pp->row, 0)))
146
return -1;
147
x += k;
148
n -= k;
149
be -= k;
150
memcpy(pz->ws.pb + pz->ws.pc, be, k);
151
pz->ws.pc += k;
152
}
153
pat = pz->pat;
154
tmp = pz->tmp;
155
low = pp->low;
156
while (bp < be)
157
{
158
if (!pz->ws.bp)
159
{
160
/*
161
* initialize for a new window
162
*/
163
164
pz->ws.io = op;
165
memcpy(pat, bp, pp->row);
166
bp += pp->row;
167
for (i = 0; i < pp->nfix; i++)
168
pat[pp->fix[i]] = pp->value[pp->fix[i]];
169
pz->ws.ve = (pz->ws.vp = pz->val) + pp->loq - 2 * pp->row;
170
memcpy(pz->ws.vp, pat, pp->row);
171
pz->ws.vp += pp->row;
172
pz->ws.bp = pz->buf;
173
for (j = 0; j < pp->nmap; j++)
174
*pz->ws.bp++ = pat[pp->map[j]];
175
pz->ws.rep = pz->ws.row = 1;
176
}
177
178
/*
179
* collect a window of hi frequency cols in buf
180
* and encode the lo frequency rows in tmp+pz->val
181
* lo frequency values must not exceed pp->loq
182
*/
183
184
k = pz->ws.row + (be - bp) / pp->row;
185
if (k > pp->col)
186
k = pp->col;
187
while (pz->ws.row < k)
188
{
189
for (j = 0; j < pp->row; j++)
190
if (pat[j] != bp[j] && low[j])
191
{
192
if (pz->ws.vp >= pz->ws.ve)
193
goto dump;
194
sfputu(tmp, pz->ws.rep);
195
sfputu(tmp, j + 1);
196
*pz->ws.vp++ = pat[j] = bp[j];
197
pz->ws.rep = 0;
198
while (++j < pp->row)
199
if (pat[j] != bp[j] && low[j])
200
{
201
sfputu(tmp, j + 1);
202
*pz->ws.vp++ = pat[j] = bp[j];
203
}
204
sfputu(tmp, 0);
205
break;
206
}
207
for (j = 0; j < pp->nmap; j++)
208
*pz->ws.bp++ = bp[pp->map[j]];
209
pz->ws.rep++;
210
pz->ws.row++;
211
bp += pp->row;
212
}
213
if (k < pp->col)
214
continue;
215
dump:
216
if (pzsync(pz))
217
return -1;
218
}
219
return n + x;
220
}
221
222