#pragma once

 #include <iostream>
#include <string> class cyclebuffer
{
protected:
volatile int32_t m_nReadIndex;
volatile int32_t m_nWriteIndex;
volatile int32_t m_nDataSize; //有效数据大小
volatile int32_t m_nBufSize; //总buf大小
uint_8 *m_pBuf; public:
cyclebuffer(int nBufSize)
{
Reset();
m_pBuf = (uint8_t *)malloc(nBufSize);
m_nbufSize = nBufSize;
} virtual ~cyclebuffer()
{
if(m_pBuf != NULL)
{
free(m_pBuf);
m_pBuf = NULL;
}
} //剩余空间数
int32_t Space()
{
return m_nBufSize-m_nDataSize;
} //获取buf的总大小
int32_t Capatity()
{
return m_nBufSize;
} //获取有效数据长度
int32_t Size()
{
return m_nDataSize;
} //清空
void Reset()
{
m_nReadIndex = ;
m_nwriteIndex = ;
m_nDataSize = ;
} //增加nSize个字节
int32_t Grow(int32_t nSize)
{
if(nSize<=)
{
return ;
} uint8_t *pMem = (uint8_t *)malloc(nSize + m_nBufSize);
if(pMem == NULL)
{
return ;
} int32_t nWriteIndex = ;
//将旧内存中的数据拷贝到(增大的)新内存中
do
{
int32_t nReadBytes = Read(pMem + nWriteIndex, );
if(nReadBytes <= )
{
break;
}
nWriteIndex += nReadBytes;
}while(m_nDataSize > ); if(m_nDataSize > )
{
return -;
} //释放旧内存块
if(m_pBuf != NULL)
{
free(m_pBuf);
} m_pBuf = pMem;
m_nReadIndex = ;
m_nWriteIndex = nWriteIndex;
m_nDataSize = nWriteIndex;
m_nBufSize += nSize; return nSize;
} //写到写列表的头部---针对新数据
int32_t WriteToHead(const uint8_t *pBuf, int32_t nDataSize)
{
if(nDataSize < || pBuf == NULL)
{
return ;
} //空间不够
if(m_nDataSize + nDataSize > m_nBufsize)
{
if(Grow((m_nDataSize+nDataSize) - m_nDataSize) <= )
{
return ;
}
} if(m_nWriteIndex < m_nReadIndex)
{
memcpy(&m_pBuf[m_nReadIndex-nDataSize], pBuf, nDataSize);
m_nReadIndex -= nDataSize;
}
else if(m_nWriteIndex == m_nReadIndex)
{
return Write(pBuf, nDataSize);
}
else
{
int32_t nLeftDataSize = (nDataSize-m_nReadIndex<)?nDataSize:m_nReadIndex;
if(nLeftDataSize < nDataSize) //此时nLeftDataSize == m_nReadIndex,m_nReadIndex前面的空间不够
{
int32_t nTailDataSize = nDataSize - nLeftDataSize;
int32_t nWriteIndex = m_nBufSize - nTailDatasize;
memcpy(&m_pBuf[nWriteIndex], pBuf, nDataSize-nLeftDataSize); //从内存最后向前写
memcpy(&m_pBuf[], pBuf+nTailDataSize, nLeftDataSize);
m_nReadIndex = nWriteIndex;
}
else
{
if(m_nReadIndex-nDataSize < )
{
return ;
}
memcpy(&m_pBuf[m_nReadIndex-nDataSize], pBuf, nDataSize);
m_nReadIndex -= nDataSize;
}
} m_nDataSize += nDataSize;
return nDataSize;
} //写到列表的尾部
int32_t Write(const uint8_t *pBuf, int32_t nDataSize)
{
if(nDataSize <= || NULL == pBuf)
{
return ;
} if(nDataSize + m_nDataSize > m_nBufSize)
{
if(Grow((nDataSize+nBufSize)-m_nDataSize) <= )
{
return ;
}
} if(m_nWriteIndex < m_nReadIndex)
{
memcpy(&m_pBuf[m_nWriteIndex], pBuf, nDataSize);
m_nWriteIndex += nDataSize;
}
else
{
int32_t nLeftDataSize = m_nBufSize - m_nWriteIndex;
if(nLeftDataSize < nDataSize)
{
memcpy(&m_pBuf[m_nWriteIndex], pBuf, nLeftDataSize);
memcpy(&m_pBuf[], pBuf+nLeftDataSize, nDataSize-nLeftDataSize);
m_nwriteIndex = nDataSize - nLeftDataSize;
}
else
{
memcpy(&m_pBuf[m_nWriteIndex], pBuf, nDataSize);
m_nWriteIndex += nDataSize;
}
}
m_nDataSize += nDataSize;
return nDataSize;
} //读取 读列表的头部内存
int32_t Read(uint8_t *pBuf, const int32_t nWantSize)
{
if(nWantSize <= || NULL == pBuf)
{
return ;
} int32_t nDataSize = ((m_nDataSize < nWantSize)?m_nDataSize : nWantSize);
if(nDataSize<=)
{
return ;
} if(m_nReadIndex < m_nWriteIndex)
{
memcpy(pBuf, &m_pBuf[m_nReadIndex], nDataSize);
m_nReadIndex += nDataSize;
}
else
{
int32_t nLeftDataSize = m_nBufSize - m_nReadIndex;
if(nLeftDataSize < nDataSize)
{
memcpy(pBuf, &m_pBuf[m_nReadIndex], nLeftDataSize);
memcpy(pBuf+nLeftDataSize, &m_pBuf[], nDataSize-nLeftDataSize);
m_nReadIndex = nDataSize-nLeftDataSize;
}
else
{
memcpy(pBuf, &m_pBuf[m_nReadIndex], nDataSize);
m_nReadIndex += nDataSize;
}
}
m_nDataSize -= nDataSize;
return nDataSize;
} //读取数据但是不修改读索引
int32_t PeekRead(uint8_t *pBuf, const int32_t nWantSize)
{
if(nWantSize <= || pBuf == NULL)
{
return ;
} int32_t nDataSize = ((m_nDataSize < nWantSize) ? m_nDataSize : nWantSize);
if(m_nReadIndex < m_nWriteIndex)
{
memcpy(pBuf, &m_pBuf[m_nReadIndex], nDataSize);
}
else if(m_nReadIndex == m_nWriteIndex)
{
return ;
}
else
{
int32_t nLeftDataSize = m_nBufSize - m_nReadIndex;
if(nLeftDataSize < nDataSize)
{
memcpy(pBuf, &m_pBuf[m_nReadIndex], nLeftDataSize);
memcpy(pBuf+nLeftDataSize, &m_pBuf[], nDataSize-nLeftDataSize);
}
else
{
memcpy(pBuf, &m_pBuf[m_nReadIndex], nDataSize);
}
}
return nDataSize;
} };

网络收发之cycleBuf的更多相关文章

  1. kernel笔记——网络收发包流程

    本文将介绍网络连接建立的过程.收发包流程,以及其中应用层.tcp层.ip层.设备层和驱动层各层发挥的作用. 应用层 对于使用socket进行网络连接的服务器端程序,我们会先调用socket函数创建一个 ...

  2. Android 网络开发之WIFI

    WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为&qu ...

  3. iOS网络开发之AFNetworking

    概述 AFNetworking是一个非常受欢迎的轻量级的iOS.Mac OS X网络通信类库.它建立在NSURLConnection.NSOperation以及其技术的基础上,有着精心设计的模块结构和 ...

  4. Android网络开发之用tcpdump抓包

    Android开发过程中,当涉及到网络通信的时候,有一些字段须要抓包获取.我之前由于SSDP设备发现的包头格式没有写对,经过抓包分析和标准包头对照发现了这个困扰我非常久的问题.总之,掌握在Androi ...

  5. Android网络开发之OkHttp--基本用法实例化各个对象

    1.实例化OkHttpClient对象,OkHttpClient包含了以下属性,以及set()和get()方法.但并没有包含具体的执行方法,详情见源码. //实例化OkHttpClent对象 priv ...

  6. Android网络开发之OkHttp--基本用法POST

    1.OkHttp框架使用了OkIo框架,不要忘记下OkIo.jar 2.通过POST访问网络,和通过GET访问网络基本相同,多了设置请求参数的过程.主要分为五步: (1).声明并实例化一个OkHttp ...

  7. Android网络开发之OkHttp--基本用法GET

    1.OkHttp框架使用了OkIo.jar包,不要忘记添加. 2.对于Request对象是如何实例化的,大家可以参考--java builder设计模式 http://www.cnblogs.com/ ...

  8. Android网络开发之Volley--Volley自定义Request

    1.自定义一个解析Json的Request,这里使用JackSon框架来解析Json.你也可以自定义一个解析XML的Request,或者使用FastSon来解析Json. 2.我们首先来看一下Stri ...

  9. Android网络开发之Volley--Volley基本用法ImageRequest(三)

    1.ImageRequest用法和StringRequest一样,主要分为3步: (1).实例化一个RequestQueue对象 (2).设置ImageRequest对象参数,并将ImageReque ...

随机推荐

  1. 定义一个runtime的Annotation

    import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(value ...

  2. C# WINFORM 线程中更新UI

    幸好今天是周末,有时间把这个问题记录一下.在多种语言之间切换,发现开发效率降的很低了,开发成本都集中到调式上了,C/C++这些放弃很久了,突然感觉线程这个问题搞的有点烦躁 我这里提到的线程中更新UI, ...

  3. html 实现网址链接

    <a href="http://acm.nyist.net/JudgeOnline/problemset.php">南工oj</a> HTML学习 < ...

  4. MySQL my.cnf 参数说明

    MySQL 5.5.13 参数说明: [client] character-set-server = utf8 port    = 3306 socket  = /data/mysql/3306/my ...

  5. android 关于多任务下载问题

    关于多任务下载问题    近期项目中,遇到一个问题,列表数据中的图片地址是一个需要下载JS再解析的字段,之前的图片下载是一个异步的过程,由一个队列处理. Android系统以不同寻常的方式处理多个应用 ...

  6. Oracle 11g RAC database on ASM, ACFS or OCFS2

    I see a lot of questions on shared file systems that can be used when people move from single instan ...

  7. 普通IT和文艺IT工程师的区别

    在一个UITableView的editing设置的方法实现过程中,我想到两种写法,顺便想了一下两种方法的区别.觉得这时一个普通IT工程师和NB工程师的区别一个有趣的印记. 您通常时怎么去实现的呢? - ...

  8. linux之iptable案例

    转自:http://blog.csdn.net/bill_lee_sh_cn/article/details/4401896 1.一对一流量完全DNAT 首先说一下网络环境,普通主机一台做防火墙用,网 ...

  9. ios7高级

    1.实现控制器和视图. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1     ...

  10. asp.net MVC过滤器的用法(转)

    转自:http://www.studyofnet.com/news/257.html APS.NET MVC中的每一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再 ...