Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1029768
  • 博文数量: 177
  • 博客积分: 3629
  • 博客等级: 中校
  • 技术积分: 1839
  • 用 户 组: 普通用户
  • 注册时间: 2005-02-23 21:21
文章分类

全部博文(177)

文章存档

2021年(1)

2020年(5)

2019年(4)

2018年(7)

2017年(1)

2016年(4)

2014年(1)

2013年(8)

2012年(10)

2011年(50)

2009年(12)

2008年(10)

2006年(56)

2005年(8)

分类: C/C++

2006-04-07 23:10:21

这篇是CircularBuffer类
用途:
在Socket类中用做高级缓冲区,接收recv的数据,把指针通过OnRawData传给用户处理。
TcpSocket::OnWrite()函数还会把本缓冲区的数据发出去(send)。
所以用了它用户不需要太多的管理缓冲区了。
分析:
利用了几个size_t变量指示数据开始,结尾,长度,最大值,实现的数据的写入与读出。

 
由于类结构不太大,罗列如下:
/** Buffer class containing one read/write circular buffer.
 \ingroup internal */
class CircularBuffer
{
public:
 CircularBuffer(Socket& owner,size_t size);//size是缓冲区的初始大小
 ~CircularBuffer();
 /** append l bytes from p to buffer */
 bool Write(const char *p,size_t l);
 /** copy l bytes from buffer to dest */
 bool Read(char *dest,size_t l);
 /** skip l bytes from buffer */
 bool Remove(size_t l);
 /** total buffer length */
 size_t GetLength();
 /** pointer to circular buffer beginning */
 char *GetStart();
 /** return number of bytes from circular buffer beginning to buffer physical end */
 size_t GetL();
 /** return free space in buffer, number of bytes until buffer overrun */
 size_t Space();
 /** return total number of bytes written to this buffer, ever */
 unsigned long ByteCounter();
private:
 Socket& GetOwner() const;
 CircularBuffer(const CircularBuffer& s) : m_owner( s.GetOwner() ) {}
 CircularBuffer& operator=(const CircularBuffer& ) { return *this; }
 Socket& m_owner;      /*缓冲区总是为Socket类准备的*/
 char *buf;            /*缓冲区指针*/
 size_t m_max;         /*数据最大值*/
 size_t m_q;          /*是数据的长度Length*/
 size_t m_b;          /*数据的开始位置*/
 size_t m_t;          /*数据的结束位置*/
 unsigned long m_count;  /*如果只调用Write,不调用read函数,返回所有写入的字节数,如果调用过read函数,返回所有写入的字节数,包括read函数中被删除的字节数*/
};
 
初始化:
CircularBuffer::CircularBuffer(Socket& owner,size_t size)
:m_owner(owner)
,buf(new char[size])
,m_max(size)
,m_q(0)
,m_b(0)
,m_t(0)
,m_count(0)
{
}
 
/*写入时只需要数据的结尾位置m_t和大小(l,m_q)一些信息,不需要知道数据的开始位置m_b,写入时不更改m_b变量,只更改m_t*/
bool CircularBuffer::Write(const char *s,size_t l) /**/
{
 if (m_q + l > m_max) //在Read函数中改变m_q的机会多,而只有m_q为0才会m_t=m_q=0,所以
 {
  m_owner.Handler().LogError(&m_owner, "CircularBuffer::Write", -1, "write buffer overflow");
  return false; // overflow
 }
 m_count += (unsigned long)l;        /*总写入的字节计数器*/
 if (m_t + l > m_max) // block crosses circular border  当read函数执行后会有可能
 {
  size_t l1 = m_max - m_t; // size left until circular border crossing
  memcpy(buf + m_t, s, l1); //原型:extern void *memcpy(void *dest, void *src, unsigned int count);
  memcpy(buf, s + l1, l - l1);
  m_t = l - l1;                 /*赋值后m_t又历经一循环,回到了l-l1处.因为此时m_t+l已大于m_max*/
  m_q += l;
 }
 else
 {
  memcpy(buf + m_t, s, l);
  m_t += l;
  if (m_t >= m_max)         /*好象最多相等哦,不可能>么*/
   m_t -= m_max;    /*m_t=m_max时m_t归零*/
  m_q += l;      /*m_q一直相加,最多等于m_max*/
 }
 return true;
}
 
/*读出时只需要数据的开始位置m_b和要读的大小l和总数据长度m_q,不需要结尾位置m_t,如s为NULL,还可起到删除的作用*/
bool CircularBuffer::Read(char *s,size_t l) /* l代表要读的长度,读时只改变m_b,m_q不改变m_t*/
{
 if (l > m_q)
 {
  m_owner.Handler().LogError(&m_owner, s ? "CircularBuffer::Read" : "CircularBuffer::Write", -1, "attempt to read beyond buffer");
  return false; // not enough chars
 }
 if (m_b + l > m_max) // block crosses circular border . m_b是起点
 {
  size_t l1 = m_max - m_b;           /* l1是后面的部分,l-l1是前面的部分*/
  if (s)
  {                                  
   memcpy(s, buf + m_b, l1);       /*这儿用 l1 代替了l,因为只有这么多的有效数据,l大点没关系*/
   memcpy(s + l1, buf, l - l1);    /* l-l1 应该最多是m_b,因为l<=m_q  */
  }
  m_b = l - l1;                       /*读完后清除被读的数据*/
  m_q -= l;                           /*m_q是数据长度,也要减去已读的数据长度 */
 }
 else
 {
  if (s)
  {
   memcpy(s, buf + m_b, l);
  }
  m_b += l;                            /*这里是正常情况,没有循环写入*/
  if (m_b >= m_max)
   m_b -= m_max;
  m_q -= l;
 }
 if (!m_q)
 {
  m_b = m_t = 0;
 }
 return true;
}
 
 
bool CircularBuffer::Remove(size_t l)
{
 return Read(NULL, l);
}
 
size_t CircularBuffer::GetLength()
{
 return m_q;
}

char *CircularBuffer::GetStart()
{
 return buf + m_b;
}

size_t CircularBuffer::GetL()
{
 return (m_b + m_q > m_max) ? m_max - m_b : m_q;
}

size_t CircularBuffer::Space()
{
 return m_max - m_q;
}

unsigned long CircularBuffer::ByteCounter()
{
 return m_count;
}

Socket& CircularBuffer::GetOwner() const
{
 return m_owner;
}
 
怎么样,这个类不错吧,COPY一下洋为中用了。
阅读(2367) | 评论(0) | 转发(0) |
0

上一篇:Socket库分析之二

下一篇:Socket库分析之四

给主人留下些什么吧!~~