9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

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 }