xref: /openbmc/u-boot/lib/circbuf.c (revision d7c11502)
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;
45 
46 	assert (buf != NULL);
47 	assert (dest != NULL);
48 
49 	p = buf->top;
50 
51 	/* Cap to number of bytes in buffer */
52 	if (len > buf->size)
53 		len = buf->size;
54 
55 	for (i = 0; i < len; i++) {
56 		dest[i] = *p++;
57 		/* Bounds check. */
58 		if (p == buf->end) {
59 			p = buf->data;
60 		}
61 	}
62 
63 	/* Update 'top' pointer */
64 	buf->top = p;
65 	buf->size -= len;
66 
67 	return len;
68 }
69 
70 int buf_push (circbuf_t * buf, const char *src, unsigned int len)
71 {
72 	/* NOTE:  this function allows push to overwrite old data. */
73 	unsigned int i;
74 	char *p;
75 
76 	assert (buf != NULL);
77 	assert (src != NULL);
78 
79 	p = buf->tail;
80 
81 	for (i = 0; i < len; i++) {
82 		*p++ = src[i];
83 		if (p == buf->end) {
84 			p = buf->data;
85 		}
86 		/* Make sure pushing too much data just replaces old data */
87 		if (buf->size < buf->totalsize) {
88 			buf->size++;
89 		} else {
90 			buf->top++;
91 			if (buf->top == buf->end) {
92 				buf->top = buf->data;
93 			}
94 		}
95 	}
96 
97 	/* Update 'tail' pointer */
98 	buf->tail = p;
99 
100 	return len;
101 }
102