00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00015 #include <ders/cycl_buf.hpp>
00016 #include <assert.h>
00017 #include <string.h>
00018
00019 namespace ders {
00020
00021 cycl_buf::cycl_buf(int rsrv)
00022 {
00023 assert(rsrv>0);
00024 sz=rsrv;
00025 buf=static_cast<char*>(operator new(sz));
00026 fst=0;
00027 cnt=0;
00028 }
00029
00030 void cycl_buf::reserve(int n)
00031 {
00032 assert(n>=0);
00033 int nsz=cnt+n;
00034 if (nsz<=sz) return;
00035
00036 if (nsz<sz*2) nsz=sz*2;
00037 char* nbuf=static_cast<char*>(operator new(nsz));
00038
00039 int n1=sz-fst;
00040 if (cnt<=n1) memcpy(nbuf, buf+fst, cnt);
00041 else {
00042 memcpy(nbuf, buf+fst, n1);
00043 memcpy(nbuf+n1, buf, cnt-n1);
00044 }
00045
00046 operator delete(buf);
00047 buf=nbuf;
00048 sz=nsz;
00049 fst=0;
00050 }
00051
00052 void cycl_buf::put(const void* ptr, int n)
00053 {
00054 assert(n>=0);
00055 if (cnt+n>sz) reserve(cnt+n);
00056
00057 int pos=(fst+cnt)%sz, n1=sz-pos;
00058 if (n<=n1) memcpy(buf+pos, ptr, n);
00059 else {
00060 memcpy(buf+pos, ptr, n1);
00061 memcpy(buf, static_cast<const char*>(ptr)+n1, n-n1);
00062 }
00063
00064 cnt+=n;
00065 }
00066
00067 void cycl_buf::put(const cycl_buf& cb)
00068 {
00069 if (cnt+cb.cnt>sz) reserve(cnt+cb.cnt);
00070
00071 if (cb.fst+cb.cnt<=cb.sz) put(cb.buf+cb.fst, cb.cnt);
00072 else {
00073 put(cb.buf+cb.fst, cb.sz-cb.fst);
00074 put(cb.buf, cb.fst+cb.cnt-cb.sz);
00075 }
00076 }
00077
00078 void cycl_buf::put_front(const void* ptr, int n)
00079 {
00080 assert(n>=0);
00081 if (cnt+n>sz) reserve(cnt+n);
00082
00083 int nfst=fst-n;
00084 if (nfst>=0) {
00085 fst=nfst;
00086 memcpy(buf+fst, ptr, n);
00087 }
00088 else {
00089 fst=sz+nfst;
00090 memcpy(buf+fst, ptr, -nfst);
00091 memcpy(buf, static_cast<const char*>(ptr)-nfst, n+nfst);
00092 }
00093
00094 cnt+=n;
00095 }
00096
00097 void cycl_buf::put_front(const cycl_buf& cb)
00098 {
00099 if (cnt+cb.cnt>sz) reserve(cnt+cb.cnt);
00100
00101 if (cb.fst+cb.cnt<=cb.sz) put_front(cb.buf+cb.fst, cb.cnt);
00102 else {
00103 put_front(cb.buf, cb.fst+cb.cnt-cb.sz);
00104 put_front(cb.buf+cb.fst, cb.sz-cb.fst);
00105 }
00106 }
00107
00108 void cycl_buf::get(void* ptr, int n)
00109 {
00110 assert(n<=cnt && n>=0);
00111
00112 int n1=sz-fst;
00113 if (n<=n1) memcpy(ptr, buf+fst, n);
00114 else {
00115 memcpy(ptr, buf+fst, n1);
00116 memcpy(static_cast<char*>(ptr)+n1, buf, n-n1);
00117 }
00118
00119 fst=(fst+n)%sz;
00120 cnt-=n;
00121 }
00122
00123 sh_cycl_buf new_cycl_buf(mem_pool& mp, int rsrv)
00124 {
00125 mp_newbuf<cycl_buf> buf(mp);
00126 return sh_cycl_buf(buf.pool(), buf.rls(::new(buf.get()) cycl_buf(rsrv)));
00127 }
00128
00129 }
00130