xref: /inferno-os/utils/mk/bufblock.c (revision d0e1d143ef6f03c75c008c7ec648859dd260cbab)
1 #include	"mk.h"
2 
3 static Bufblock *freelist;
4 #define	QUANTA	4096
5 
6 Bufblock *
7 newbuf(void)
8 {
9 	Bufblock *p;
10 
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 }
24 
25 void
26 freebuf(Bufblock *p)
27 {
28 	p->next = freelist;
29 	freelist = p;
30 }
31 
32 void
33 growbuf(Bufblock *p)
34 {
35 	int n;
36 	Bufblock *f;
37 	char *cp;
38 
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 }
60 
61 void
62 bufcpy(Bufblock *buf, char *cp, int n)
63 {
64 
65 	while (n--)
66 		insert(buf, *cp++);
67 }
68 
69 void
70 insert(Bufblock *buf, int c)
71 {
72 
73 	if (buf->current >= buf->end)
74 		growbuf(buf);
75 	*buf->current++ = c;
76 }
77 
78 void
79 rinsert(Bufblock *buf, Rune r)
80 {
81 	int n;
82 
83 	n = runelen(r);
84 	if (buf->current+n > buf->end)
85 		growbuf(buf);
86 	runetochar(buf->current, &r);
87 	buf->current += n;
88 }
89