zoukankan      html  css  js  c++  java
  • 环形缓冲区的实现

    环形缓冲区

    //缓存区大小
    #define PM_BUF_SIZE 1024
    
    //获取当前缓冲区的数据个数
    #define circ_cnt(head, tail, size) (((head) > (tail)) ? \
    		((head) - (tail)) : \
    		((head) - (tail)) & ((size) - 1))
    
    //计算缓冲区的可写大小
    #define circ_space(head, tail, size) circ_cnt((tail), ((head) + 1), (size))
    
    //把指针n移动1个位置
    #define circ_inc(n, s) (((n) + 1) % (s))
    
    //把指针n移动v个位置
    #define circ_add(n, v, s) (((n) + (v)) % (s))
    
    //返回小的数
    #define min(a, b)              \
        ({                         \
            typeof(a) __a = (a);   \
            typeof(b) __b = (b);   \
            __a < __b ? __a : __b; \
        })
    
    int GetData(char* buff, int pwr, int &prd, char *bufret, int size)
    {
    	int pr = prd, i = 0;
    	char *tmpx= bufret;
    	char ch = '\0';
    	int bitflag = 0;
    	int cnt = 0;
    
    	*bufret = 0;
    
        
    	while (circ_cnt(pwr, pr, PM_BUF_SIZE) > 0) {
    
    		ch = buff[pr];
            //pr指针指向下一个位置
    		pr = circ_inc(pr, PM_BUF_SIZE);  // 读指针超出环形缓冲区末尾,会返回头部
    		switch(ch)
    		{
                //假设S为数据头
    			case 'S':			
    			bitflag = 1;
    			bufret[i++] = ch;
    			break;
    			
                //假设E为数据尾
    			case 'E':
    				if ((bitflag & 0x1) == 0x1) {
    					bitflag |= 0x2;
    					bufret[i++] = ch;
    				}
    				break;
                 
                //只有当接收到数据头时,将有效数据写入bufert中
    			default:
    			if (bitflag & 0x1) {
    				bufret[i++] = ch;
    			}
    			break;
    		}
    		
    		if (i >= size)
    			break;
    
    		if (bitflag & 0x3) {
    			break;
    		}
    	}
    	
    	if ((bitflag & 0x3) == 0x3) {
            //进入这里就表示接收到了一段有效的数据
    		prd = pr;
    		bufret[i++] = 0;
    		return 1;
    	} else {	
    		return 0;
    	}
    }
    
    void RingBufferLoop()
    {
        int pw = 0; //写指针
    	int pr = 0; //读指针
        char p_buf[PM_BUF_SIZE];
    	int ret;
    	char temp[128] = {0};
    
        while(1) {
            // * min(circ_space(pw, pr, PM_BUF_SIZE), (PM_BUF_SIZE - pw))的
            // * 作用就是计算出缓冲区可写的大小。
          ret = read(fd, &p_buf[pw], min(circ_space(pw, pr, PM_BUF_SIZE), (PM_BUF_SIZE - pw)));  
          if(ret > 0)
          {
              //接收到了数据
              //把pw指向最后一个字符
              pw = circ_add(pw, ret, PM_BUF_SIZE);
              
              //在结尾添加\0
              p_buf[circ_inc(pw, PM_BUF_SIZE)] = '\0';   
          }
            
           //检查缓冲区中是否有数据,如果有就处理
          while (circ_cnt(pw, pr, PM_BUF_SIZE) > 0)
          {
              //将有效数据段放入temp中
              ret = GetData(p_buf, pw, pr, temp, sizeof(temp));
              if(!ret)
                 break; //当前没有有效数据段
              
              processbuf(temp); //处理有效数据temp
          }
            
        }
        
    }
    
  • 相关阅读:
    Git的分支的clone、提交及删除
    Linux查找整个目录下包含关键词的文件并全局替换文件内容
    解决Mysql group_concat长度限制
    SQLSERVER建立MYSQL连接服务器
    批处理创建文件夹
    表分区常用脚本
    添加别名的重要性
    floor相关
    T-SQL 小数点转换百分数
    开启MSDTC
  • 原文地址:https://www.cnblogs.com/r1chie/p/15630296.html
Copyright © 2011-2022 走看看