1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  *
4  */
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include "boot_ringbuffer.h"
11 
boot_ringbuff_reset(boot_ringbuff_t * rb)12 int32_t boot_ringbuff_reset(boot_ringbuff_t *rb)
13 {
14 	if (!rb) {
15 		return -1;
16 	}
17 
18 	rb->rd_ptr = rb->buffer;
19 	rb->wr_ptr = rb->buffer;
20 	rb->dirty_size = 0;
21 	rb->free_size = rb->buffer_end - rb->buffer;
22 	return 0;
23 }
24 
boot_ringbuff_init(boot_ringbuff_t * rb,uint8_t * buffer,int32_t size)25 int32_t boot_ringbuff_init(boot_ringbuff_t *rb,	uint8_t *buffer, int32_t size)
26 {
27 	if (!rb) {
28 		return -1;
29 	}
30 
31 	if (!buffer) {
32 		return -1;
33 	}
34 
35 	if (size <= 4) {
36 		return -1;
37 	}
38 
39 	rb->buffer = buffer;
40 	rb->buffer_end = rb->buffer + size;
41 	boot_ringbuff_reset(rb);
42 	return 0;
43 }
44 
boot_ringbuff_freesize(boot_ringbuff_t * rb)45 int32_t boot_ringbuff_freesize(boot_ringbuff_t *rb)
46 {
47 	if (!rb) {
48 		return -1;
49 	}
50 	return rb->free_size;
51 }
52 
boot_ringbuff_dirtysize(boot_ringbuff_t * rb)53 int32_t boot_ringbuff_dirtysize(boot_ringbuff_t *rb)
54 {
55 	if (!rb) {
56 		return -1;
57 	}
58 	return rb->dirty_size;
59 }
60 
boot_ringbuff_fill(boot_ringbuff_t * rb,uint8_t * buffer,int32_t size)61 int32_t boot_ringbuff_fill(boot_ringbuff_t *rb, uint8_t *buffer, int32_t size)
62 {
63 	if (!rb) {
64 		return -1;
65 	}
66 
67 	if (size > rb->free_size || size <= 0) {
68 		return -1;
69 	}
70 
71 	if ((rb->buffer_end - rb->wr_ptr >= size &&
72 		rb->wr_ptr >= rb->rd_ptr) ||
73 		rb->wr_ptr < rb->rd_ptr) {
74 		memcpy(rb->wr_ptr, buffer, size);
75 		rb->wr_ptr += size;
76 		rb->dirty_size += size;
77 		rb->free_size -= size;
78 		if (rb->wr_ptr >= rb->buffer_end)
79 			rb->wr_ptr = rb->buffer;
80 	} else if (rb->buffer_end - rb->wr_ptr < size &&
81 		rb->wr_ptr >= rb->rd_ptr) {
82 		int temp = rb->buffer_end - rb->wr_ptr;
83 		memcpy(rb->wr_ptr, buffer, temp);
84 		rb->wr_ptr = rb->buffer;
85 		memcpy(rb->wr_ptr, buffer + temp, size - temp);
86 		rb->dirty_size += size;
87 		rb->free_size -= size;
88 		rb->wr_ptr += size - temp;
89 	} else {
90 		return -1;
91 	}
92 
93 	return size;
94 }
95 
boot_ringbuff_read(boot_ringbuff_t * rb,uint8_t * buffer,int32_t size)96 int32_t boot_ringbuff_read(boot_ringbuff_t *rb,	uint8_t *buffer, int32_t size)
97 {
98 	if (!rb) {
99 		return -1;
100 	}
101 
102 	if (size > rb->dirty_size || size <= 0) {
103 		return -1;
104 	}
105 
106 	if (rb->rd_ptr < rb->wr_ptr &&
107 		rb->wr_ptr - rb->rd_ptr >= size) {
108 		memcpy(buffer, rb->rd_ptr, size);
109 		rb->dirty_size -= size;
110 		rb->free_size += size;
111 		rb->rd_ptr += size;
112 	} else if (rb->rd_ptr >= rb->wr_ptr) {
113 		if (rb->buffer_end - rb->rd_ptr >= size) {
114 			memcpy(buffer, rb->rd_ptr, size);
115 			rb->dirty_size -= size;
116 			rb->free_size += size;
117 			rb->rd_ptr += size;
118 			if (rb->rd_ptr >= rb->buffer_end)
119 				rb->rd_ptr = rb->buffer;
120 		} else {
121 			int temp = rb->buffer_end - rb->rd_ptr;
122 			memcpy(buffer, rb->rd_ptr, temp);
123 			rb->rd_ptr = rb->buffer;
124 			memcpy(buffer + temp, rb->rd_ptr, size - temp);
125 			rb->dirty_size -= size;
126 			rb->free_size += size;
127 			rb->rd_ptr += size - temp;
128 		}
129 	} else {
130 		return -1;
131 	}
132 
133 	return size;
134 }
135 
136 
137 
138