#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. mvn command is not recognized as an internal or external command

    even though I have configured %m2_home% and %path% correctly, the command "mvn" is still n ...

  2. OSG选中效果展示

    <OpenSceneGraph三维渲染引擎编程指南>书中选中高亮效果示例.osgFX特效 2.得到鼠标的位置 osgFX特效1.高亮,在开头的时候写了: 2.线框: #include< ...

  3. CFBundleName系列参数的含义

    顺带讲一下其他这些选项表示什么意思: CFBundleName: CFBundleName指定了该束的简称.简称应该小于16个字符并且适合在菜单和“关于”中显示.通过把它加入到适当的.lproj子文件 ...

  4. 01-复杂度2. Maximum Subsequence Sum (25)

    Given a sequence of K integers { N1, N2, ..., NK }. A continuous subsequence is defined to be { Ni, ...

  5. 命令行方式运行yii2程序

    测试环境,yii 2.0.3版本 web访问方式,控制器放在controllers目录下 ,浏览器访问如下地址 http://127.0.0.1/index.php?r=[controller-nam ...

  6. redis 缓存技术与memcache的最大差别

    1 什么是redis  redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对很多其它,包含string(字符串).list(链表).set(集合)和zs ...

  7. 2.Freshman阶段学习内容的确定

    我刷知乎.在知乎上答题的程序员,不是很牛逼就是更牛逼,说起各种系统.各种系统的各种版本.各种语言.数据库.算法.IT届的各种圣战都有板有眼.信手拈来.头头是道,不得不服.这导致了一些非常严重的问题:我 ...

  8. Clementine 12.0 的使用(因为比较少用,项目中用到才开始接触写一下自己的使用方法)

    首先我是根据excel的文件做的训练,就以excel来做介绍 1.打开Clementine 12.0 软件 点击软件下方的 ”源“ 即你要做训练的数据源.因为是excel文件双击excel. 2.双击 ...

  9. JS图表组件 highcharts 简单的介绍

    把highcharts拿来做个简单的介绍,希望更多的朋友可以用到这个用来做图表的js插件. preparation Highcharts Highcharts是一个制作图表的纯Javascript类库 ...

  10. JavaSE学习总结第26天_网络编程

      26.01  网络编程概述 网络编程:就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换. 26.02  网络模型概述和图解 计算机网络之间以何种规则进行通信,就是网络模型研究问题. ...