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