cycl_buf.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) Sergey P. Derevyago, 2008-2009.
00003  *
00004  * Permission to copy, use, modify, sell and distribute this software is granted
00005  * provided this copyright notice appears in all copies.
00006  * This software is provided "as is" without express or implied warranty, and
00007  * with no claim as to its suitability for any purpose.
00008  *
00009  */
00010 
00015 #include <ders/cycl_buf.hpp>
00016 #include <assert.h>
00017 #include <string.h>
00018 
00019 namespace ders {  // ::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 }  // namespace ::ders
00130 

Generated on Tue Dec 8 11:35:32 2009 for derslib by  doxygen 1.5.5