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