2 * Buffer management functions
3 * Copyright (C) 2008 Andreas Ă–man
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
32 #define MIN(a, b) ((a) < (b) ? (a) : (b))
36 #define MAX(a, b) ((a) > (b) ? (a) : (b))
44 htsbuf_queue_init(htsbuf_queue_t *hq, unsigned int maxsize)
48 TAILQ_INIT(&hq->hq_q);
50 hq->hq_maxsize = maxsize;
58 htsbuf_data_free(htsbuf_queue_t *hq, htsbuf_data_t *hd)
60 TAILQ_REMOVE(&hq->hq_q, hd, hd_link);
70 htsbuf_queue_flush(htsbuf_queue_t *hq)
76 while((hd = TAILQ_FIRST(&hq->hq_q)) != NULL)
77 htsbuf_data_free(hq, hd);
84 htsbuf_append(htsbuf_queue_t *hq, const char *buf, size_t len)
86 htsbuf_data_t *hd = TAILQ_LAST(&hq->hq_q, htsbuf_data_queue);
91 /* Fill out any previous buffer */
92 c = MIN(hd->hd_data_size - hd->hd_data_len, len);
93 memcpy(hd->hd_data + hd->hd_data_len, buf, c);
101 hd = malloc(sizeof(htsbuf_data_t));
102 TAILQ_INSERT_TAIL(&hq->hq_q, hd, hd_link);
104 c = MAX(len, 1000); /* Allocate 1000 bytes to support lots of small writes */
106 hd->hd_data = malloc(c);
107 hd->hd_data_size = c;
108 hd->hd_data_len = len;
110 memcpy(hd->hd_data, buf, len);
117 htsbuf_append_prealloc(htsbuf_queue_t *hq, const char *buf, size_t len)
123 hd = malloc(sizeof(htsbuf_data_t));
124 TAILQ_INSERT_TAIL(&hq->hq_q, hd, hd_link);
126 hd->hd_data = (void *)buf;
127 hd->hd_data_size = len;
128 hd->hd_data_len = len;
136 htsbuf_read(htsbuf_queue_t *hq, char *buf, size_t len)
144 hd = TAILQ_FIRST(&hq->hq_q);
148 c = MIN(hd->hd_data_len - hd->hd_data_off, len);
149 memcpy(buf, hd->hd_data + hd->hd_data_off, c);
154 hd->hd_data_off += c;
156 if(hd->hd_data_off == hd->hd_data_len)
157 htsbuf_data_free(hq, hd);
167 htsbuf_find(htsbuf_queue_t *hq, uint8_t v)
170 unsigned int i, o = 0;
172 TAILQ_FOREACH(hd, &hq->hq_q, hd_link) {
173 for(i = hd->hd_data_off; i < hd->hd_data_len; i++) {
174 if(hd->hd_data[i] == v)
175 return o + i - hd->hd_data_off;
177 o += hd->hd_data_len - hd->hd_data_off;
188 htsbuf_peek(htsbuf_queue_t *hq, char *buf, size_t len)
193 htsbuf_data_t *hd = TAILQ_FIRST(&hq->hq_q);
195 while(len > 0 && hd != NULL) {
196 c = MIN(hd->hd_data_len - hd->hd_data_off, len);
197 memcpy(buf, hd->hd_data + hd->hd_data_off, c);
202 hd = TAILQ_NEXT(hd, hd_link);
211 htsbuf_drop(htsbuf_queue_t *hq, size_t len)
218 hd = TAILQ_FIRST(&hq->hq_q);
222 c = MIN(hd->hd_data_len - hd->hd_data_off, len);
224 hd->hd_data_off += c;
226 if(hd->hd_data_off == hd->hd_data_len)
227 htsbuf_data_free(hq, hd);
236 htsbuf_vqprintf(htsbuf_queue_t *hq, const char *fmt, va_list ap)
239 htsbuf_append(hq, buf, vsnprintf(buf, sizeof(buf), fmt, ap));
247 htsbuf_qprintf(htsbuf_queue_t *hq, const char *fmt, ...)
251 htsbuf_vqprintf(hq, fmt, ap);