Blob


1 #include "mk.h"
3 static Bufblock *freelist;
4 #define QUANTA 4096
6 Bufblock *
7 newbuf(void)
8 {
9 Bufblock *p;
11 if (freelist) {
12 p = freelist;
13 freelist = freelist->next;
14 } else {
15 p = (Bufblock *) Malloc(sizeof(Bufblock));
16 p->start = Malloc(QUANTA*sizeof(*p->start));
17 p->end = p->start+QUANTA;
18 }
19 p->current = p->start;
20 *p->start = 0;
21 p->next = 0;
22 return p;
23 }
25 void
26 freebuf(Bufblock *p)
27 {
28 p->next = freelist;
29 freelist = p;
30 }
32 void
33 growbuf(Bufblock *p)
34 {
35 int n;
36 Bufblock *f;
37 char *cp;
39 n = p->end-p->start+QUANTA;
40 /* search the free list for a big buffer */
41 for (f = freelist; f; f = f->next) {
42 if (f->end-f->start >= n) {
43 memcpy(f->start, p->start, p->end-p->start);
44 cp = f->start;
45 f->start = p->start;
46 p->start = cp;
47 cp = f->end;
48 f->end = p->end;
49 p->end = cp;
50 f->current = f->start;
51 break;
52 }
53 }
54 if (!f) { /* not found - grow it */
55 p->start = Realloc(p->start, n);
56 p->end = p->start+n;
57 }
58 p->current = p->start+n-QUANTA;
59 }
61 void
62 bufcpy(Bufblock *buf, char *cp, int n)
63 {
65 while (n--)
66 insert(buf, *cp++);
67 }
69 void
70 insert(Bufblock *buf, int c)
71 {
73 if (buf->current >= buf->end)
74 growbuf(buf);
75 *buf->current++ = c;
76 }
78 void
79 rinsert(Bufblock *buf, Rune r)
80 {
81 int n;
83 n = runelen(r);
84 if (buf->current+n > buf->end)
85 growbuf(buf);
86 runetochar(buf->current, &r);
87 buf->current += n;
88 }