Blame


1 b3994ec5 2003-12-11 devnull #include <u.h>
2 b3994ec5 2003-12-11 devnull #include <libc.h>
3 b3994ec5 2003-12-11 devnull #include <draw.h>
4 b3994ec5 2003-12-11 devnull #include <thread.h>
5 b3994ec5 2003-12-11 devnull #include <cursor.h>
6 b3994ec5 2003-12-11 devnull #include <mouse.h>
7 b3994ec5 2003-12-11 devnull #include <keyboard.h>
8 b3994ec5 2003-12-11 devnull #include <frame.h>
9 b3994ec5 2003-12-11 devnull #include <fcall.h>
10 b3994ec5 2003-12-11 devnull #include <plumb.h>
11 67dbeee5 2017-10-10 rsc #include <libsec.h>
12 b3994ec5 2003-12-11 devnull #include "dat.h"
13 b3994ec5 2003-12-11 devnull #include "fns.h"
14 b3994ec5 2003-12-11 devnull
15 b3994ec5 2003-12-11 devnull enum
16 b3994ec5 2003-12-11 devnull {
17 cbeb0b26 2006-04-01 devnull Slop = 100 /* room to grow with reallocation */
18 b3994ec5 2003-12-11 devnull };
19 b3994ec5 2003-12-11 devnull
20 b3994ec5 2003-12-11 devnull static
21 b3994ec5 2003-12-11 devnull void
22 b3994ec5 2003-12-11 devnull sizecache(Buffer *b, uint n)
23 b3994ec5 2003-12-11 devnull {
24 b3994ec5 2003-12-11 devnull if(n <= b->cmax)
25 b3994ec5 2003-12-11 devnull return;
26 b3994ec5 2003-12-11 devnull b->cmax = n+Slop;
27 b3994ec5 2003-12-11 devnull b->c = runerealloc(b->c, b->cmax);
28 b3994ec5 2003-12-11 devnull }
29 b3994ec5 2003-12-11 devnull
30 b3994ec5 2003-12-11 devnull static
31 b3994ec5 2003-12-11 devnull void
32 b3994ec5 2003-12-11 devnull addblock(Buffer *b, uint i, uint n)
33 b3994ec5 2003-12-11 devnull {
34 b3994ec5 2003-12-11 devnull if(i > b->nbl)
35 b3994ec5 2003-12-11 devnull error("internal error: addblock");
36 b3994ec5 2003-12-11 devnull
37 b3994ec5 2003-12-11 devnull b->bl = realloc(b->bl, (b->nbl+1)*sizeof b->bl[0]);
38 b3994ec5 2003-12-11 devnull if(i < b->nbl)
39 b3994ec5 2003-12-11 devnull memmove(b->bl+i+1, b->bl+i, (b->nbl-i)*sizeof(Block*));
40 b3994ec5 2003-12-11 devnull b->bl[i] = disknewblock(disk, n);
41 b3994ec5 2003-12-11 devnull b->nbl++;
42 b3994ec5 2003-12-11 devnull }
43 b3994ec5 2003-12-11 devnull
44 b3994ec5 2003-12-11 devnull static
45 b3994ec5 2003-12-11 devnull void
46 b3994ec5 2003-12-11 devnull delblock(Buffer *b, uint i)
47 b3994ec5 2003-12-11 devnull {
48 b3994ec5 2003-12-11 devnull if(i >= b->nbl)
49 b3994ec5 2003-12-11 devnull error("internal error: delblock");
50 b3994ec5 2003-12-11 devnull
51 b3994ec5 2003-12-11 devnull diskrelease(disk, b->bl[i]);
52 b3994ec5 2003-12-11 devnull b->nbl--;
53 b3994ec5 2003-12-11 devnull if(i < b->nbl)
54 b3994ec5 2003-12-11 devnull memmove(b->bl+i, b->bl+i+1, (b->nbl-i)*sizeof(Block*));
55 b3994ec5 2003-12-11 devnull b->bl = realloc(b->bl, b->nbl*sizeof b->bl[0]);
56 b3994ec5 2003-12-11 devnull }
57 b3994ec5 2003-12-11 devnull
58 b3994ec5 2003-12-11 devnull /*
59 b3994ec5 2003-12-11 devnull * Move cache so b->cq <= q0 < b->cq+b->cnc.
60 b3994ec5 2003-12-11 devnull * If at very end, q0 will fall on end of cache block.
61 b3994ec5 2003-12-11 devnull */
62 b3994ec5 2003-12-11 devnull
63 b3994ec5 2003-12-11 devnull static
64 b3994ec5 2003-12-11 devnull void
65 b3994ec5 2003-12-11 devnull flush(Buffer *b)
66 b3994ec5 2003-12-11 devnull {
67 b3994ec5 2003-12-11 devnull if(b->cdirty || b->cnc==0){
68 b3994ec5 2003-12-11 devnull if(b->cnc == 0)
69 b3994ec5 2003-12-11 devnull delblock(b, b->cbi);
70 b3994ec5 2003-12-11 devnull else
71 b3994ec5 2003-12-11 devnull diskwrite(disk, &b->bl[b->cbi], b->c, b->cnc);
72 b3994ec5 2003-12-11 devnull b->cdirty = FALSE;
73 b3994ec5 2003-12-11 devnull }
74 b3994ec5 2003-12-11 devnull }
75 b3994ec5 2003-12-11 devnull
76 b3994ec5 2003-12-11 devnull static
77 b3994ec5 2003-12-11 devnull void
78 b3994ec5 2003-12-11 devnull setcache(Buffer *b, uint q0)
79 b3994ec5 2003-12-11 devnull {
80 b3994ec5 2003-12-11 devnull Block **blp, *bl;
81 b3994ec5 2003-12-11 devnull uint i, q;
82 b3994ec5 2003-12-11 devnull
83 b3994ec5 2003-12-11 devnull if(q0 > b->nc)
84 b3994ec5 2003-12-11 devnull error("internal error: setcache");
85 b3994ec5 2003-12-11 devnull /*
86 b3994ec5 2003-12-11 devnull * flush and reload if q0 is not in cache.
87 b3994ec5 2003-12-11 devnull */
88 b3994ec5 2003-12-11 devnull if(b->nc == 0 || (b->cq<=q0 && q0<b->cq+b->cnc))
89 b3994ec5 2003-12-11 devnull return;
90 b3994ec5 2003-12-11 devnull /*
91 b3994ec5 2003-12-11 devnull * if q0 is at end of file and end of cache, continue to grow this block
92 b3994ec5 2003-12-11 devnull */
93 b3994ec5 2003-12-11 devnull if(q0==b->nc && q0==b->cq+b->cnc && b->cnc<Maxblock)
94 b3994ec5 2003-12-11 devnull return;
95 b3994ec5 2003-12-11 devnull flush(b);
96 b3994ec5 2003-12-11 devnull /* find block */
97 b3994ec5 2003-12-11 devnull if(q0 < b->cq){
98 b3994ec5 2003-12-11 devnull q = 0;
99 b3994ec5 2003-12-11 devnull i = 0;
100 b3994ec5 2003-12-11 devnull }else{
101 b3994ec5 2003-12-11 devnull q = b->cq;
102 b3994ec5 2003-12-11 devnull i = b->cbi;
103 b3994ec5 2003-12-11 devnull }
104 b3994ec5 2003-12-11 devnull blp = &b->bl[i];
105 b3994ec5 2003-12-11 devnull while(q+(*blp)->u.n <= q0 && q+(*blp)->u.n < b->nc){
106 b3994ec5 2003-12-11 devnull q += (*blp)->u.n;
107 b3994ec5 2003-12-11 devnull i++;
108 b3994ec5 2003-12-11 devnull blp++;
109 b3994ec5 2003-12-11 devnull if(i >= b->nbl)
110 b3994ec5 2003-12-11 devnull error("block not found");
111 b3994ec5 2003-12-11 devnull }
112 b3994ec5 2003-12-11 devnull bl = *blp;
113 b3994ec5 2003-12-11 devnull /* remember position */
114 b3994ec5 2003-12-11 devnull b->cbi = i;
115 b3994ec5 2003-12-11 devnull b->cq = q;
116 b3994ec5 2003-12-11 devnull sizecache(b, bl->u.n);
117 b3994ec5 2003-12-11 devnull b->cnc = bl->u.n;
118 b3994ec5 2003-12-11 devnull /*read block*/
119 b3994ec5 2003-12-11 devnull diskread(disk, bl, b->c, b->cnc);
120 b3994ec5 2003-12-11 devnull }
121 b3994ec5 2003-12-11 devnull
122 b3994ec5 2003-12-11 devnull void
123 b3994ec5 2003-12-11 devnull bufinsert(Buffer *b, uint q0, Rune *s, uint n)
124 b3994ec5 2003-12-11 devnull {
125 b3994ec5 2003-12-11 devnull uint i, m, t, off;
126 b3994ec5 2003-12-11 devnull
127 b3994ec5 2003-12-11 devnull if(q0 > b->nc)
128 b3994ec5 2003-12-11 devnull error("internal error: bufinsert");
129 b3994ec5 2003-12-11 devnull
130 b3994ec5 2003-12-11 devnull while(n > 0){
131 b3994ec5 2003-12-11 devnull setcache(b, q0);
132 b3994ec5 2003-12-11 devnull off = q0-b->cq;
133 b3994ec5 2003-12-11 devnull if(b->cnc+n <= Maxblock){
134 b3994ec5 2003-12-11 devnull /* Everything fits in one block. */
135 b3994ec5 2003-12-11 devnull t = b->cnc+n;
136 b3994ec5 2003-12-11 devnull m = n;
137 b3994ec5 2003-12-11 devnull if(b->bl == nil){ /* allocate */
138 b3994ec5 2003-12-11 devnull if(b->cnc != 0)
139 b3994ec5 2003-12-11 devnull error("internal error: bufinsert1 cnc!=0");
140 b3994ec5 2003-12-11 devnull addblock(b, 0, t);
141 b3994ec5 2003-12-11 devnull b->cbi = 0;
142 b3994ec5 2003-12-11 devnull }
143 b3994ec5 2003-12-11 devnull sizecache(b, t);
144 b3994ec5 2003-12-11 devnull runemove(b->c+off+m, b->c+off, b->cnc-off);
145 b3994ec5 2003-12-11 devnull runemove(b->c+off, s, m);
146 b3994ec5 2003-12-11 devnull b->cnc = t;
147 b3994ec5 2003-12-11 devnull goto Tail;
148 b3994ec5 2003-12-11 devnull }
149 b3994ec5 2003-12-11 devnull /*
150 b3994ec5 2003-12-11 devnull * We must make a new block. If q0 is at
151 b3994ec5 2003-12-11 devnull * the very beginning or end of this block,
152 b3994ec5 2003-12-11 devnull * just make a new block and fill it.
153 b3994ec5 2003-12-11 devnull */
154 b3994ec5 2003-12-11 devnull if(q0==b->cq || q0==b->cq+b->cnc){
155 b3994ec5 2003-12-11 devnull if(b->cdirty)
156 b3994ec5 2003-12-11 devnull flush(b);
157 b3994ec5 2003-12-11 devnull m = min(n, Maxblock);
158 b3994ec5 2003-12-11 devnull if(b->bl == nil){ /* allocate */
159 b3994ec5 2003-12-11 devnull if(b->cnc != 0)
160 b3994ec5 2003-12-11 devnull error("internal error: bufinsert2 cnc!=0");
161 b3994ec5 2003-12-11 devnull i = 0;
162 b3994ec5 2003-12-11 devnull }else{
163 b3994ec5 2003-12-11 devnull i = b->cbi;
164 b3994ec5 2003-12-11 devnull if(q0 > b->cq)
165 b3994ec5 2003-12-11 devnull i++;
166 b3994ec5 2003-12-11 devnull }
167 b3994ec5 2003-12-11 devnull addblock(b, i, m);
168 b3994ec5 2003-12-11 devnull sizecache(b, m);
169 b3994ec5 2003-12-11 devnull runemove(b->c, s, m);
170 b3994ec5 2003-12-11 devnull b->cq = q0;
171 b3994ec5 2003-12-11 devnull b->cbi = i;
172 b3994ec5 2003-12-11 devnull b->cnc = m;
173 b3994ec5 2003-12-11 devnull goto Tail;
174 b3994ec5 2003-12-11 devnull }
175 b3994ec5 2003-12-11 devnull /*
176 b3994ec5 2003-12-11 devnull * Split the block; cut off the right side and
177 b3994ec5 2003-12-11 devnull * let go of it.
178 b3994ec5 2003-12-11 devnull */
179 b3994ec5 2003-12-11 devnull m = b->cnc-off;
180 b3994ec5 2003-12-11 devnull if(m > 0){
181 b3994ec5 2003-12-11 devnull i = b->cbi+1;
182 b3994ec5 2003-12-11 devnull addblock(b, i, m);
183 b3994ec5 2003-12-11 devnull diskwrite(disk, &b->bl[i], b->c+off, m);
184 b3994ec5 2003-12-11 devnull b->cnc -= m;
185 b3994ec5 2003-12-11 devnull }
186 b3994ec5 2003-12-11 devnull /*
187 b3994ec5 2003-12-11 devnull * Now at end of block. Take as much input
188 b3994ec5 2003-12-11 devnull * as possible and tack it on end of block.
189 b3994ec5 2003-12-11 devnull */
190 b3994ec5 2003-12-11 devnull m = min(n, Maxblock-b->cnc);
191 b3994ec5 2003-12-11 devnull sizecache(b, b->cnc+m);
192 b3994ec5 2003-12-11 devnull runemove(b->c+b->cnc, s, m);
193 b3994ec5 2003-12-11 devnull b->cnc += m;
194 b3994ec5 2003-12-11 devnull Tail:
195 b3994ec5 2003-12-11 devnull b->nc += m;
196 b3994ec5 2003-12-11 devnull q0 += m;
197 b3994ec5 2003-12-11 devnull s += m;
198 b3994ec5 2003-12-11 devnull n -= m;
199 b3994ec5 2003-12-11 devnull b->cdirty = TRUE;
200 b3994ec5 2003-12-11 devnull }
201 b3994ec5 2003-12-11 devnull }
202 b3994ec5 2003-12-11 devnull
203 b3994ec5 2003-12-11 devnull void
204 b3994ec5 2003-12-11 devnull bufdelete(Buffer *b, uint q0, uint q1)
205 b3994ec5 2003-12-11 devnull {
206 b3994ec5 2003-12-11 devnull uint m, n, off;
207 b3994ec5 2003-12-11 devnull
208 b3994ec5 2003-12-11 devnull if(!(q0<=q1 && q0<=b->nc && q1<=b->nc))
209 b3994ec5 2003-12-11 devnull error("internal error: bufdelete");
210 b3994ec5 2003-12-11 devnull while(q1 > q0){
211 b3994ec5 2003-12-11 devnull setcache(b, q0);
212 b3994ec5 2003-12-11 devnull off = q0-b->cq;
213 b3994ec5 2003-12-11 devnull if(q1 > b->cq+b->cnc)
214 b3994ec5 2003-12-11 devnull n = b->cnc - off;
215 b3994ec5 2003-12-11 devnull else
216 b3994ec5 2003-12-11 devnull n = q1-q0;
217 b3994ec5 2003-12-11 devnull m = b->cnc - (off+n);
218 b3994ec5 2003-12-11 devnull if(m > 0)
219 b3994ec5 2003-12-11 devnull runemove(b->c+off, b->c+off+n, m);
220 b3994ec5 2003-12-11 devnull b->cnc -= n;
221 b3994ec5 2003-12-11 devnull b->cdirty = TRUE;
222 b3994ec5 2003-12-11 devnull q1 -= n;
223 b3994ec5 2003-12-11 devnull b->nc -= n;
224 b3994ec5 2003-12-11 devnull }
225 b3994ec5 2003-12-11 devnull }
226 b3994ec5 2003-12-11 devnull
227 b3994ec5 2003-12-11 devnull static int
228 b3994ec5 2003-12-11 devnull bufloader(void *v, uint q0, Rune *r, int nr)
229 b3994ec5 2003-12-11 devnull {
230 b3994ec5 2003-12-11 devnull bufinsert(v, q0, r, nr);
231 b3994ec5 2003-12-11 devnull return nr;
232 b3994ec5 2003-12-11 devnull }
233 b3994ec5 2003-12-11 devnull
234 b3994ec5 2003-12-11 devnull uint
235 67dbeee5 2017-10-10 rsc loadfile(int fd, uint q0, int *nulls, int(*f)(void*, uint, Rune*, int), void *arg, DigestState *h)
236 b3994ec5 2003-12-11 devnull {
237 b3994ec5 2003-12-11 devnull char *p;
238 b3994ec5 2003-12-11 devnull Rune *r;
239 b3994ec5 2003-12-11 devnull int l, m, n, nb, nr;
240 b3994ec5 2003-12-11 devnull uint q1;
241 b3994ec5 2003-12-11 devnull
242 b3994ec5 2003-12-11 devnull p = emalloc((Maxblock+UTFmax+1)*sizeof p[0]);
243 b3994ec5 2003-12-11 devnull r = runemalloc(Maxblock);
244 b3994ec5 2003-12-11 devnull m = 0;
245 b3994ec5 2003-12-11 devnull n = 1;
246 b3994ec5 2003-12-11 devnull q1 = q0;
247 b3994ec5 2003-12-11 devnull /*
248 b3994ec5 2003-12-11 devnull * At top of loop, may have m bytes left over from
249 b3994ec5 2003-12-11 devnull * last pass, possibly representing a partial rune.
250 b3994ec5 2003-12-11 devnull */
251 b3994ec5 2003-12-11 devnull while(n > 0){
252 b3994ec5 2003-12-11 devnull n = read(fd, p+m, Maxblock);
253 b3994ec5 2003-12-11 devnull if(n < 0){
254 b3994ec5 2003-12-11 devnull warning(nil, "read error in Buffer.load");
255 b3994ec5 2003-12-11 devnull break;
256 b3994ec5 2003-12-11 devnull }
257 67dbeee5 2017-10-10 rsc if(h != nil)
258 67dbeee5 2017-10-10 rsc sha1((uchar*)p+m, n, nil, h);
259 b3994ec5 2003-12-11 devnull m += n;
260 b3994ec5 2003-12-11 devnull p[m] = 0;
261 b3994ec5 2003-12-11 devnull l = m;
262 b3994ec5 2003-12-11 devnull if(n > 0)
263 b3994ec5 2003-12-11 devnull l -= UTFmax;
264 b3994ec5 2003-12-11 devnull cvttorunes(p, l, r, &nb, &nr, nulls);
265 b3994ec5 2003-12-11 devnull memmove(p, p+nb, m-nb);
266 b3994ec5 2003-12-11 devnull m -= nb;
267 b3994ec5 2003-12-11 devnull q1 += (*f)(arg, q1, r, nr);
268 b3994ec5 2003-12-11 devnull }
269 b3994ec5 2003-12-11 devnull free(p);
270 b3994ec5 2003-12-11 devnull free(r);
271 b3994ec5 2003-12-11 devnull return q1-q0;
272 b3994ec5 2003-12-11 devnull }
273 b3994ec5 2003-12-11 devnull
274 b3994ec5 2003-12-11 devnull uint
275 67dbeee5 2017-10-10 rsc bufload(Buffer *b, uint q0, int fd, int *nulls, DigestState *h)
276 b3994ec5 2003-12-11 devnull {
277 b3994ec5 2003-12-11 devnull if(q0 > b->nc)
278 b3994ec5 2003-12-11 devnull error("internal error: bufload");
279 67dbeee5 2017-10-10 rsc return loadfile(fd, q0, nulls, bufloader, b, h);
280 b3994ec5 2003-12-11 devnull }
281 b3994ec5 2003-12-11 devnull
282 b3994ec5 2003-12-11 devnull void
283 b3994ec5 2003-12-11 devnull bufread(Buffer *b, uint q0, Rune *s, uint n)
284 b3994ec5 2003-12-11 devnull {
285 b3994ec5 2003-12-11 devnull uint m;
286 b3994ec5 2003-12-11 devnull
287 b3994ec5 2003-12-11 devnull if(!(q0<=b->nc && q0+n<=b->nc))
288 b3994ec5 2003-12-11 devnull error("bufread: internal error");
289 b3994ec5 2003-12-11 devnull
290 b3994ec5 2003-12-11 devnull while(n > 0){
291 b3994ec5 2003-12-11 devnull setcache(b, q0);
292 b3994ec5 2003-12-11 devnull m = min(n, b->cnc-(q0-b->cq));
293 b3994ec5 2003-12-11 devnull runemove(s, b->c+(q0-b->cq), m);
294 b3994ec5 2003-12-11 devnull q0 += m;
295 b3994ec5 2003-12-11 devnull s += m;
296 b3994ec5 2003-12-11 devnull n -= m;
297 b3994ec5 2003-12-11 devnull }
298 b3994ec5 2003-12-11 devnull }
299 b3994ec5 2003-12-11 devnull
300 b3994ec5 2003-12-11 devnull void
301 b3994ec5 2003-12-11 devnull bufreset(Buffer *b)
302 b3994ec5 2003-12-11 devnull {
303 b3994ec5 2003-12-11 devnull int i;
304 b3994ec5 2003-12-11 devnull
305 b3994ec5 2003-12-11 devnull b->nc = 0;
306 b3994ec5 2003-12-11 devnull b->cnc = 0;
307 b3994ec5 2003-12-11 devnull b->cq = 0;
308 b3994ec5 2003-12-11 devnull b->cdirty = 0;
309 b3994ec5 2003-12-11 devnull b->cbi = 0;
310 b3994ec5 2003-12-11 devnull /* delete backwards to avoid n² behavior */
311 b3994ec5 2003-12-11 devnull for(i=b->nbl-1; --i>=0; )
312 b3994ec5 2003-12-11 devnull delblock(b, i);
313 b3994ec5 2003-12-11 devnull }
314 b3994ec5 2003-12-11 devnull
315 b3994ec5 2003-12-11 devnull void
316 b3994ec5 2003-12-11 devnull bufclose(Buffer *b)
317 b3994ec5 2003-12-11 devnull {
318 b3994ec5 2003-12-11 devnull bufreset(b);
319 b3994ec5 2003-12-11 devnull free(b->c);
320 b3994ec5 2003-12-11 devnull b->c = nil;
321 b3994ec5 2003-12-11 devnull b->cnc = 0;
322 b3994ec5 2003-12-11 devnull free(b->bl);
323 b3994ec5 2003-12-11 devnull b->bl = nil;
324 b3994ec5 2003-12-11 devnull b->nbl = 0;
325 b3994ec5 2003-12-11 devnull }