69 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
| /* $Revision: 1.7 $
 | |
|  */
 | |
| 
 | |
| /* `Buffer' is a dynamically growing, general-purpose buffer data
 | |
|  * structure.
 | |
|  *
 | |
|  * buffer_new(size)         --  returns new buffer with initial size `size'
 | |
|  *                              or some default size if argument is zero
 | |
|  * buffer_delete(b)         --  marks a buffer as unused
 | |
|  * buffer_clear(b)          --  empties a buffer
 | |
|  * buffer_puts(b,data,len)  --  appends data to a buffer, growing it if
 | |
|  *                              necessary
 | |
|  * buffer_putc(b,c)         --  appends a character to a buffer
 | |
|  */
 | |
| 
 | |
| #include "unroff.h"
 | |
| 
 | |
| static int sizeinc_linear(Buffer *);
 | |
| 
 | |
| static Buffer *first_free;
 | |
| 
 | |
| Buffer *buffer_new(int size) {
 | |
|     Buffer *p;
 | |
| 
 | |
|     if (size == 0)
 | |
| 	size = 512;
 | |
|     if (first_free) {    /* reuse a buffer if there is one */
 | |
| 	p = first_free;
 | |
| 	first_free = p->next;
 | |
| 	if (p->max < size) {
 | |
| 	    free(p->data);
 | |
| 	    p->data = safe_malloc(p->max = size);
 | |
| 	}
 | |
|     } else {
 | |
| 	p = safe_malloc(sizeof *p);
 | |
| 	p->data = safe_malloc(size);
 | |
| 	p->increment = p->max = size;
 | |
| 	p->sizeinc_func = sizeinc_linear;
 | |
|     }
 | |
|     buffer_clear(p);
 | |
|     return p;
 | |
| }
 | |
| 
 | |
| void buffer_delete(Buffer *p) {
 | |
|     assert(p->size >= 0);
 | |
|     p->size = -1;
 | |
|     p->next = first_free;
 | |
|     first_free = p;
 | |
| }
 | |
| 
 | |
| void buffer_grow(Buffer *p) {
 | |
|     p->max = p->sizeinc_func(p);
 | |
|     p->data = safe_realloc(p->data, p->max);
 | |
| }
 | |
| 
 | |
| void buffer_puts(Buffer *p, char *s, int size) {
 | |
|     assert(size >= 0);
 | |
|     while (p->size + size > p->max)
 | |
| 	buffer_grow(p);
 | |
|     if (size == 0)
 | |
| 	return;
 | |
|     memcpy(p->data+p->size, s, size);
 | |
|     p->size += size;
 | |
| }
 | |
| 
 | |
| static int sizeinc_linear(Buffer *p) {
 | |
|     return p->max + p->increment;
 | |
| }
 |