xref: /openbmc/u-boot/lib/circbuf.c (revision 569a191a)
1 /*
2  * (C) Copyright 2003
3  * Gerry Hamel, geh@ti.com, Texas Instruments
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <common.h>
9 #include <malloc.h>
10 
11 #include <circbuf.h>
12 
13 
14 int buf_init (circbuf_t * buf, unsigned int size)
15 {
16 	assert (buf != NULL);
17 
18 	buf->size = 0;
19 	buf->totalsize = size;
20 	buf->data = (char *) malloc (sizeof (char) * size);
21 	assert (buf->data != NULL);
22 
23 	buf->top = buf->data;
24 	buf->tail = buf->data;
25 	buf->end = &(buf->data[size]);
26 
27 	return 1;
28 }
29 
30 int buf_free (circbuf_t * buf)
31 {
32 	assert (buf != NULL);
33 	assert (buf->data != NULL);
34 
35 	free (buf->data);
36 	memset (buf, 0, sizeof (circbuf_t));
37 
38 	return 1;
39 }
40 
41 int buf_pop (circbuf_t * buf, char *dest, unsigned int len)
42 {
43 	unsigned int i;
44 	char *p = buf->top;
45 
46 	assert (buf != NULL);
47 	assert (dest != NULL);
48 
49 	/* Cap to number of bytes in buffer */
50 	if (len > buf->size)
51 		len = buf->size;
52 
53 	for (i = 0; i < len; i++) {
54 		dest[i] = *p++;
55 		/* Bounds check. */
56 		if (p == buf->end) {
57 			p = buf->data;
58 		}
59 	}
60 
61 	/* Update 'top' pointer */
62 	buf->top = p;
63 	buf->size -= len;
64 
65 	return len;
66 }
67 
68 int buf_push (circbuf_t * buf, const char *src, unsigned int len)
69 {
70 	/* NOTE:  this function allows push to overwrite old data. */
71 	unsigned int i;
72 	char *p = buf->tail;
73 
74 	assert (buf != NULL);
75 	assert (src != NULL);
76 
77 	for (i = 0; i < len; i++) {
78 		*p++ = src[i];
79 		if (p == buf->end) {
80 			p = buf->data;
81 		}
82 		/* Make sure pushing too much data just replaces old data */
83 		if (buf->size < buf->totalsize) {
84 			buf->size++;
85 		} else {
86 			buf->top++;
87 			if (buf->top == buf->end) {
88 				buf->top = buf->data;
89 			}
90 		}
91 	}
92 
93 	/* Update 'tail' pointer */
94 	buf->tail = p;
95 
96 	return len;
97 }
98