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 }