bufblock.c (1338B)
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 }