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