1*b4d5e3c9Sratchov /* $OpenBSD: abuf.c,v 1.32 2024/12/22 14:17:45 ratchov Exp $ */ 2d0585044Sratchov /* 310ba9548Sratchov * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> 4d0585044Sratchov * 5d0585044Sratchov * Permission to use, copy, modify, and distribute this software for any 6d0585044Sratchov * purpose with or without fee is hereby granted, provided that the above 7d0585044Sratchov * copyright notice and this permission notice appear in all copies. 8d0585044Sratchov * 9d0585044Sratchov * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10d0585044Sratchov * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11d0585044Sratchov * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12d0585044Sratchov * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13d0585044Sratchov * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14d0585044Sratchov * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15d0585044Sratchov * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16d0585044Sratchov */ 17d0585044Sratchov /* 1810ba9548Sratchov * Simple byte fifo. 19d0585044Sratchov * 20d0585044Sratchov * The abuf data is split in two parts: (1) valid data available to the reader 21d0585044Sratchov * (2) space available to the writer, which is not necessarily unused. It works 22d0585044Sratchov * as follows: the write starts filling at offset (start + used), once the data 23d0585044Sratchov * is ready, the writer adds to used the count of bytes available. 249bb28defSratchov */ 25dfd73bc8Sratchov #include "abuf.h" 2610ba9548Sratchov #include "utils.h" 27fcda7a7eSratchov 28015dec6cSratchov void 2910ba9548Sratchov abuf_init(struct abuf *buf, unsigned int len) 30015dec6cSratchov { 3110ba9548Sratchov buf->data = xmalloc(len); 3210ba9548Sratchov buf->len = len; 33baead350Sratchov buf->used = 0; 34baead350Sratchov buf->start = 0; 35baead350Sratchov } 36baead350Sratchov 3710ba9548Sratchov void 3810ba9548Sratchov abuf_done(struct abuf *buf) 3910ba9548Sratchov { 4010ba9548Sratchov #ifdef DEBUG 41*b4d5e3c9Sratchov if (buf->used > 0) 42*b4d5e3c9Sratchov logx(3, "deleting non-empty buffer, used = %d", buf->used); 4310ba9548Sratchov #endif 44572ed201Sratchov xfree(buf->data); 4510ba9548Sratchov buf->data = (void *)0xdeadbeef; 4610ba9548Sratchov } 4710ba9548Sratchov 48baead350Sratchov /* 4910ba9548Sratchov * return the reader pointer and the number of bytes available 50d0585044Sratchov */ 51d0585044Sratchov unsigned char * 5210ba9548Sratchov abuf_rgetblk(struct abuf *buf, int *rsize) 53d0585044Sratchov { 5410ba9548Sratchov int count; 55d0585044Sratchov 5610ba9548Sratchov count = buf->len - buf->start; 5710ba9548Sratchov if (count > buf->used) 5810ba9548Sratchov count = buf->used; 59d0585044Sratchov *rsize = count; 6010ba9548Sratchov return buf->data + buf->start; 61d0585044Sratchov } 62d0585044Sratchov 63d0585044Sratchov /* 64d9a51c35Sjmc * discard "count" bytes at the start position. 65d2641806Sratchov */ 66d2641806Sratchov void 6710ba9548Sratchov abuf_rdiscard(struct abuf *buf, int count) 68d2641806Sratchov { 69015dec6cSratchov #ifdef DEBUG 7010ba9548Sratchov if (count < 0 || count > buf->used) { 71*b4d5e3c9Sratchov logx(0, "%s: bad count = %d", __func__, count); 7210ba9548Sratchov panic(); 73dec09956Sratchov } 74015dec6cSratchov #endif 75d2641806Sratchov buf->used -= count; 76d2641806Sratchov buf->start += count; 77d2641806Sratchov if (buf->start >= buf->len) 78d2641806Sratchov buf->start -= buf->len; 79d2641806Sratchov } 80d2641806Sratchov 81d2641806Sratchov /* 8210ba9548Sratchov * advance the writer pointer by "count" bytes 83d2641806Sratchov */ 84d2641806Sratchov void 8510ba9548Sratchov abuf_wcommit(struct abuf *buf, int count) 86d2641806Sratchov { 87015dec6cSratchov #ifdef DEBUG 8810ba9548Sratchov if (count < 0 || count > (buf->len - buf->used)) { 89*b4d5e3c9Sratchov logx(0, "%s: bad count = %d", __func__, count); 9010ba9548Sratchov panic(); 91dec09956Sratchov } 92015dec6cSratchov #endif 93d2641806Sratchov buf->used += count; 94d2641806Sratchov } 95d2641806Sratchov 96d2641806Sratchov /* 9710ba9548Sratchov * get writer pointer and the number of bytes writable 98d0585044Sratchov */ 99d0585044Sratchov unsigned char * 10010ba9548Sratchov abuf_wgetblk(struct abuf *buf, int *rsize) 101d0585044Sratchov { 10210ba9548Sratchov int end, avail, count; 103d0585044Sratchov 10410ba9548Sratchov end = buf->start + buf->used; 105d0585044Sratchov if (end >= buf->len) 106d0585044Sratchov end -= buf->len; 10710ba9548Sratchov avail = buf->len - buf->used; 108d0585044Sratchov count = buf->len - end; 109d0585044Sratchov if (count > avail) 110d0585044Sratchov count = avail; 111d0585044Sratchov *rsize = count; 11210ba9548Sratchov return buf->data + end; 113d0585044Sratchov } 114