-
Notifications
You must be signed in to change notification settings - Fork 2
/
circbuf.c
57 lines (48 loc) · 1.06 KB
/
circbuf.c
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
#include <stdlib.h>
#include <assert.h>
#include "circbuf.h"
typedef struct Circbuf{
void **data;
int sz,len,base;
void (*deleteitem)(void*);
} Circbuf;
Circbuf* cb_make(int size,void (*deleteitem)(void*)){
Circbuf *cb=malloc(sizeof(Circbuf));
if(!cb)return NULL;
cb->data=calloc(size,sizeof(char*));
if(!cb->data){
free(cb);
return NULL;
}
cb->sz=size;
cb->len=0;
cb->base=0;
cb->deleteitem=deleteitem;
return cb;
}
void cb_destroy(Circbuf *cb){
cb_clear(cb);
free(cb);
}
void cb_append(Circbuf *cb,void *item){
int index=(cb->base+cb->len)%cb->sz;
if(cb->data[index])cb->deleteitem(cb->data[index]);
cb->data[index]=item;
if(cb->len==cb->sz)cb->base=(cb->base+1)%cb->sz;
else cb->len++;
}
void cb_clear(Circbuf *cb){
for(int i=0;i<cb->len;i++){
cb->deleteitem(cb->data[(cb->base+i)%cb->sz]);
cb->data[(cb->base+i)%cb->sz]=NULL;
}
cb->len=0;
}
void* cb_get(Circbuf *cb,int index){
assert(-cb->len<=index&&index<cb->len);
if(index<0)index+=cb->len;
return cb->data[(cb->base+index)%cb->sz];
}
int cb_length(Circbuf *cb){
return cb->len;
}