00001
00002
00003
00004
00005
00006
00007
#include "wvmagiccircle.h"
00008
#include <assert.h>
00009
00010
00011 WvMagicCircle::WvMagicCircle(size_t _size)
00012 : shm(_size + 1 + 2*sizeof(int)),
00013 head(((int*)shm.buf)[0]), tail(((int*)shm.buf)[1])
00014 {
00015 assert((
int)_size > 0);
00016
00017
head =
tail = 0;
00018
size = _size + 1;
00019
circle =
shm.
cbuf + 2*
sizeof(
int);
00020
00021
if (
shm.
geterr())
00022 seterr(
shm);
00023 }
00024
00025
00026 WvMagicCircle::~WvMagicCircle()
00027 {
00028
00029 }
00030
00031
00032 size_t
WvMagicCircle::used()
00033 {
00034
int x =
tail -
head;
00035
if (x < 0)
00036 x +=
size;
00037 assert(x >= 0);
00038 assert(x < size);
00039
00040
return x;
00041 }
00042
00043
00044 size_t
WvMagicCircle::put(
const void *data, size_t len)
00045 {
00046 size_t max =
left();
00047 size_t chunk1;
00048
00049
if (len > max)
00050 len = max;
00051
00052 chunk1 =
size -
tail;
00053
if (len < chunk1)
00054 chunk1 = len;
00055
00056
#if 0
00057
WvLog log(
"put", WvLog::Info);
00058
log(
"put: head %s, tail %s, size %s, len %s, chunk1 %s\n",
00059
head, tail,
size, len, chunk1);
00060
#endif
00061
00062 memcpy(
circle + tail, data, chunk1);
00063
if (chunk1 < len)
00064 memcpy(
circle, (
char *)data + chunk1, len - chunk1);
00065
00066 tail = (tail + len) %
size;
00067
00068
return len;
00069 }
00070
00071
00072 size_t
WvMagicCircle::get(
void *data, size_t len)
00073 {
00074 size_t max =
used();
00075 size_t chunk1;
00076
00077
if (len > max)
00078 len = max;
00079
00080 chunk1 =
size -
head;
00081
if (chunk1 > len)
00082 chunk1 = len;
00083
00084 memcpy(data,
circle + head, chunk1);
00085
if (chunk1 < len)
00086 memcpy((
char *)data + chunk1,
circle, len - chunk1);
00087
00088 head = (head + len) %
size;
00089
00090
return len;
00091 }
00092
00093
00094 size_t
WvMagicCircle::skip(size_t len)
00095 {
00096 size_t max =
used();
00097
00098
if (len > max)
00099 len = max;
00100
00101
head = (
head + len) %
size;
00102
00103
return len;
00104 }