-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathringbuffer.c
More file actions
205 lines (163 loc) · 5.11 KB
/
ringbuffer.c
File metadata and controls
205 lines (163 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "list.h"
#include "ringbuffer.h"
ringbuffer_block_t *ringbuffer_block_new( size_t nSize )
{
ringbuffer_block_t *ringbuf_data = NULL;
if ( nSize < RINGBUFFER_DEFAULT_DATA_SIZE )
{
nSize = RINGBUFFER_DEFAULT_DATA_SIZE;
}
ringbuf_data = (ringbuffer_block_t *)malloc( sizeof( ringbuffer_block_t ) + nSize );
ringbuf_data->data = (unsigned char *)&ringbuf_data[1];
ringbuf_data->maxsize = nSize;
ringbuf_data->cursize = 0;
ringbuf_data->noffset = 0;
return ringbuf_data;
}
void ringbuffer_block_free( ringbuffer_block_t *ringbuf_block )
{
free( ringbuf_block );
}
void ringbuffer_init( ringbuffer_t *ringbuf )
{
ringbuf->block_count = 0;
ringbuf->length = 0;
InitializeMPListEntry( &ringbuf->block_head );
}
void ringbuffer_clear( ringbuffer_t *ringbuf )
{
ringbuffer_block_t *ringbuf_data;
while ( ringbuf->block_head.next != ringbuf->block_head.prev )
{
ringbuf_data = MPListLastEntry( &ringbuf->block_head, ringbuffer_block_t, Entry );
MPRemoveEntryList( &ringbuf_data->Entry );
ringbuf->block_count--;
ringbuffer_block_free( ringbuf_data );
}
ringbuf->length = 0;
}
void ringbuffer_destroy( ringbuffer_t *ringbuf )
{
ringbuffer_block_t *ringbuf_data;
while ( !MPListIsEmpty( &ringbuf->block_head ) )
{
ringbuf_data = MPListLastEntry( &ringbuf->block_head, ringbuffer_block_t, Entry );
MPRemoveEntryList( &ringbuf_data->Entry );
ringbuf->block_count--;
ringbuffer_block_free( ringbuf_data );
}
ringbuf->length = 0;
}
int ringbuffer_write( ringbuffer_t *ringbuf, const unsigned char *buffer, size_t size )
{
ringbuffer_block_t *ringbuf_block;
if ( MPListIsEmpty( &ringbuf->block_head ) )
{
ringbuf_block = ringbuffer_block_new( size );
if ( ringbuf_block == NULL )
{
return RB_NO_MEMORY;
}
MPListInsertToHead( &ringbuf->block_head, &ringbuf_block->Entry );
ringbuf->block_count++;
}
else
{
ringbuf_block = MPListFirstEntry( &ringbuf->block_head, ringbuffer_block_t, Entry );
}
if ( ringbuf->length == 0 )
{
ringbuf_block->noffset = 0;
ringbuf_block->cursize = 0;
}
//如果ringbuffer的分块足够容纳所有数据 则直接复制数据进去
if ( ringbuf_block->maxsize > ringbuf_block->cursize + size )
{
memcpy( &ringbuf_block->data[ringbuf_block->cursize], buffer, size );
ringbuf_block->cursize += size;
ringbuf->length += size;
return RB_SUCCESS;
}
//ringbuffer分块无法容纳所有数据,循环写入不同分块
size_t lastsize = size;
const unsigned char *input_data = buffer;
while ( lastsize > 0 )
{
if ( ringbuf_block->maxsize - ringbuf_block->cursize == 0 ) //如果ringbuf_data没有剩余数据 则执行新建数据
{
ringbuf_block = ringbuffer_block_new( lastsize );
if ( ringbuf_block == NULL )
{
return RB_NO_MEMORY;
}
MPListInsertToHead( &ringbuf->block_head, &ringbuf_block->Entry );
ringbuf->block_count++;
//追加数据到申请的分块内 并更新剩余大小
size_t copylen = min( ringbuf_block->maxsize - ringbuf_block->cursize, lastsize );
memcpy( &ringbuf_block->data[ringbuf_block->cursize], input_data, copylen );
ringbuf_block->cursize += copylen;
//移动指针位置
input_data += copylen;
lastsize -= copylen;
ringbuf->length += copylen;
}
else
{
//追加数据
size_t copylen = min( ringbuf_block->maxsize - ringbuf_block->cursize, lastsize );
memcpy( &ringbuf_block->data[ringbuf_block->cursize], input_data, copylen );
ringbuf_block->cursize += copylen;
input_data += copylen;
lastsize -= copylen;
ringbuf->length += copylen;
}
}
return RB_SUCCESS;
}
size_t ringbuffer_read( ringbuffer_t *ringbuf, unsigned char *buffer, size_t size )
{
if ( ringbuf->length == 0 )
return 0;
size_t totalread = min( ringbuf->length, size );
size_t nread = 0;
ringbuffer_block_t *current_block = MPListLastEntry( &ringbuf->block_head, ringbuffer_block_t, Entry );
unsigned char *target = buffer;
while ( nread < totalread )
{
size_t readlen = min( current_block->cursize - current_block->noffset, totalread - nread );
memcpy( target, current_block->data + current_block->noffset, readlen );
current_block->noffset += readlen;
nread += readlen;
target += readlen;
ringbuf->length -= readlen;
//BLOCK数据全部读取完成判断
if ( current_block->noffset == current_block->cursize )
{
if ( current_block->cursize < current_block->maxsize )//如果数据已经读完了就跳出循环
{
break;
}
//BLOCK全部被读完,而且BLOCK已经全部被使用则释放掉这块内存
ringbuffer_block_t *ringbuf_temp = current_block;
current_block = (ringbuffer_block_t *)current_block->Entry.prev;
MPRemoveEntryList( &ringbuf_temp->Entry );
ringbuffer_block_free( ringbuf_temp );
ringbuf->block_count--;
if ( MPListIsEmpty( &ringbuf->block_head ) ) //如果列表是空的就直接跳出循环
break;
}
}
return nread;
}
size_t ringbuffer_read2( ringbuffer_t *ringbuf, unsigned char *buffer, size_t size )
{
if ( ringbuf->length == 0 )
return 0;
if ( ringbuf->length < size )
return 0;
return ringbuffer_read( ringbuf, buffer, size );
}