1 /*
2  * Buffer handling functions
3  *
4  * Copyright (C) 2003, Olaf Kirch <okir@suse.de>
5  */
6 
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <openct/buffer.h>
14 
ct_buf_init(ct_buf_t * bp,void * mem,size_t len)15 void ct_buf_init(ct_buf_t * bp, void *mem, size_t len)
16 {
17 	memset(bp, 0, sizeof(*bp));
18 	bp->base = (unsigned char *)mem;
19 	bp->size = len;
20 }
21 
ct_buf_set(ct_buf_t * bp,void * mem,size_t len)22 void ct_buf_set(ct_buf_t * bp, void *mem, size_t len)
23 {
24 	ct_buf_init(bp, mem, len);
25 	bp->tail = len;
26 }
27 
ct_buf_clear(ct_buf_t * bp)28 void ct_buf_clear(ct_buf_t * bp)
29 {
30 	bp->head = bp->tail = 0;
31 }
32 
ct_buf_get(ct_buf_t * bp,void * mem,size_t len)33 int ct_buf_get(ct_buf_t * bp, void *mem, size_t len)
34 {
35 	if (len > bp->tail - bp->head)
36 		return -1;
37 	if (mem)
38 		memcpy(mem, bp->base + bp->head, len);
39 	bp->head += len;
40 	return len;
41 }
42 
ct_buf_gets(ct_buf_t * bp,char * buffer,size_t size)43 int ct_buf_gets(ct_buf_t * bp, char *buffer, size_t size)
44 {
45 	unsigned int n, avail;
46 	unsigned char *s;
47 
48 	size -= 1;		/* room for NUL byte */
49 
50 	/* Limit string to what we have */
51 	avail = bp->tail - bp->head;
52 	if (size > avail)
53 		size = avail;
54 
55 	/* Look for newline */
56 	s = bp->base + bp->head;
57 	for (n = 0; n < size && s[n] != '\n'; n++) ;
58 
59 	/* Copy string (excluding newline) */
60 	memcpy(buffer, s, n);
61 	buffer[n] = '\0';
62 
63 	/* And eat any characters that weren't copied
64 	 * (including the newline)
65 	 */
66 	while (n < avail && s[n++] != '\n') ;
67 
68 	bp->head += n;
69 	return 0;
70 }
71 
ct_buf_put(ct_buf_t * bp,const void * mem,size_t len)72 int ct_buf_put(ct_buf_t * bp, const void *mem, size_t len)
73 {
74 	if (len > bp->size - bp->tail)
75 		ct_buf_compact(bp);
76 	if (len > bp->size - bp->tail) {
77 		bp->overrun = 1;
78 		return -1;
79 	}
80 	if (mem)
81 		memcpy(bp->base + bp->tail, mem, len);
82 	bp->tail += len;
83 	return len;
84 }
85 
ct_buf_push(ct_buf_t * bp,const void * mem,size_t len)86 int ct_buf_push(ct_buf_t * bp, const void *mem, size_t len)
87 {
88 	if (bp->head < len)
89 		return -1;
90 	bp->head -= len;
91 	if (mem)
92 		memcpy(bp->base + bp->head, mem, len);
93 	return len;
94 }
95 
ct_buf_putc(ct_buf_t * bp,int byte)96 int ct_buf_putc(ct_buf_t * bp, int byte)
97 {
98 	unsigned char c = byte;
99 
100 	return ct_buf_put(bp, &c, 1);
101 }
102 
ct_buf_puts(ct_buf_t * bp,const char * string)103 int ct_buf_puts(ct_buf_t * bp, const char *string)
104 {
105 	return ct_buf_put(bp, string, strlen(string));
106 }
107 
ct_buf_avail(ct_buf_t * bp)108 unsigned int ct_buf_avail(ct_buf_t * bp)
109 {
110 	return bp->tail - bp->head;
111 }
112 
ct_buf_tailroom(ct_buf_t * bp)113 unsigned int ct_buf_tailroom(ct_buf_t * bp)
114 {
115 	return bp->size - bp->tail;
116 }
117 
ct_buf_size(ct_buf_t * bp)118 unsigned int ct_buf_size(ct_buf_t * bp)
119 {
120 	return bp->size;
121 }
122 
ct_buf_head(ct_buf_t * bp)123 void *ct_buf_head(ct_buf_t * bp)
124 {
125 	return bp->base + bp->head;
126 }
127 
ct_buf_tail(ct_buf_t * bp)128 void *ct_buf_tail(ct_buf_t * bp)
129 {
130 	return bp->base + bp->tail;
131 }
132 
ct_buf_read(ct_buf_t * bp,int fd)133 int ct_buf_read(ct_buf_t * bp, int fd)
134 {
135 	unsigned int count;
136 	int n;
137 
138 	ct_buf_compact(bp);
139 
140 	count = bp->size - bp->tail;
141 	if ((n = read(fd, bp->base + bp->tail, count)) < 0)
142 		return -1;
143 	bp->tail += n;
144 	return 0;
145 }
146 
ct_buf_compact(ct_buf_t * bp)147 void ct_buf_compact(ct_buf_t * bp)
148 {
149 	unsigned int count;
150 
151 	if (bp->head == 0)
152 		return;
153 
154 	count = bp->tail - bp->head;
155 	memmove(bp->base, bp->base + bp->head, count);
156 	bp->tail -= bp->head;
157 	bp->head = 0;
158 }
159 
ct_buf_overrun(ct_buf_t * bp)160 int ct_buf_overrun(ct_buf_t * bp)
161 {
162 	return bp->overrun;
163 }
164