【C++】设计用户级缓冲区

news2024/9/28 16:30:00

目录

缓冲区功能分析

缓冲区空间分配策略分析

数据设计和函数介绍

完整代码

接口介绍


个人主页:东洛的克莱斯韦克-CSDN博客

缓冲区功能分析

        1.可以向缓冲区写入数据

        2.可用从缓冲区读取数据

        3.可用窥探数据——把数据拷贝给上层,但缓冲区数据不减少

        4.可以读取一行——以\n    \r\n   \r 结尾算一行

        5.可以获取缓冲区可读数据的大小

        6.可以清空缓冲区,数据

缓冲区空间分配策略分析

空间划分

        缓冲区初始值为1024个字节,用两个下标(分别是读下标和写下标)把空间分为三段

        第一段:0下标到读下标(左闭右开),这段为剩余空间

        第二段:读下标到写下标(左闭右开),这段为可读数据

        第三段:写下标到空间末尾(左闭右开),这段为剩余空间

扩容策略

        1.写入数据的大小小于等于第三段空间,直接写入

        2.写入的数据的大小小于等于第一段空间大小加第三段空间大小,把可读数据拷贝到空间的开头,在写入数据

        3,写入的数据大小大于等于第一段空间大小加第三段空间大小,直接扩容,然后在第三段写入数据。

        上述策略中的第二点,是为了不让空间一直扩容,扩容很大概率都是异地扩容,也需要拷贝,这是有代价的。

数据设计和函数介绍

        底层的容器用std::vector<char>类型。两个下标用uint64_t类型

【C++】详解STL容器之一的 vector_c++ vector扩容缩容-CSDN博客

    std::vector<char> _buff;    //缓冲区
    uint64_t _read_pos;         //读下标
    uint64_t _write_pos;        //写下标

拷贝数据用std::copy,第一个参数:从哪里拷贝的起始地址,第二个参数:从哪里拷贝的末尾地址,第三参数:从拷贝到哪里的起始地址。

查找字符用C语言的strchr,第一个参数:一段空间的起始地址,第二个参数:要查找字符的ASCII,找到了返回字符的地址,失败返回nullptr

完整代码

#include <vector>
#include <cstdint> 
#include <assert.h>
#include <algorithm>
#include <string>
#include <iostream>
#include <cstring>

#define BUFF_MAX_SIZE 1024  //容器大小的初始值


class Buff{
    private:
    std::vector<char> _buff;    //缓冲区
    uint64_t _read_pos;         //读下标
    uint64_t _write_pos;        //写下标
    private:
       //获取容器起始地址
    char* GetInitPos(){ return &( *_buff.begin());   }
    //获取读位置地址
    char* GetReadPos(){ return GetInitPos() + _read_pos; }
    //获取写位置地址
    char* GetWritePos(){    return GetInitPos() + _write_pos;   }
    //缓冲区读位置之后有多少空闲空间,把空间分为了三段,第一段
    uint64_t FirstParagraphV(){     return _read_pos;   }
      //可读数据大小,第二段
    uint64_t SecondParagraphV(){    return _write_pos - _read_pos;  }
    //缓冲区写位置之前有多少空闲空间,第三段
    uint64_t ThirdParagraphV(){     return _buff.capacity() - _write_pos;   }
    //读偏移移动
    void MoveReadPos(uint64_t len){
        assert(len <= SecondParagraphV());
        _read_pos += len;
    }
    //写偏移移动
    void MoveWritePos(uint64_t len){
        assert(len <= ThirdParagraphV());
        _write_pos += len;
    }
    //确保足够空间
    void EnsureSpaceEnough(uint64_t len){
        if (len <= ThirdParagraphV()){
            return;
        }       
        else if ( len <= FirstParagraphV() + ThirdParagraphV()){
            std::copy(GetReadPos(), GetWritePos(), GetInitPos());
            _write_pos = SecondParagraphV();
            _read_pos = 0;
        }
        else{   _buff.reserve(_buff.capacity() + len);  }
    }
    public:
    //构造
    Buff():_read_pos(0), _write_pos(0), _buff(BUFF_MAX_SIZE){   }
    //可读数据大小]
    uint64_t ReadSize(){    return SecondParagraphV();  }
    //写入数据
    void Write(const char* date, uint64_t len){
        EnsureSpaceEnough(len); //确保空间足够
        std::copy(date, date + len, GetWritePos());     //写入数据
        MoveWritePos(len);  //移动下标
    }
    void Write(const std::string& date, uint64_t len){  Write(&date[0], len);   }
    void Write(Buff& date, uint64_t len){   Write(date.GetReadPos(), len);  }
    //窥探数据
    void pry(char* buf, uint64_t len){
        assert(len <= SecondParagraphV());
        std::copy(GetReadPos(), GetReadPos() + len, buf);
    }
    void pry(std::string& buf, uint64_t len){   pry(&(*buf.begin()), len);   }
    void pry(Buff& buf, uint64_t len){  pry(buf.GetWritePos(), len);    }
    //读取数据
    void Read(char* buf, uint64_t len){
        assert(len <= SecondParagraphV());
        std::copy(GetReadPos(), GetReadPos() + len, buf);
        MoveReadPos(len);
    }
    void Read(std::string& buf, uint64_t len){   Read(&(*buf.begin()), len);   }
    void Read(Buff& buf, uint64_t len){  Read(buf.GetWritePos(), len);    }
    //读取一行
    bool ReadLen(std::string& str){
        //\n   \r\n   /r
        char c = '\n';
        char* pos_ptr = strchr(GetInitPos(), c);
        if (nullptr == pos_ptr){
            c = '\r';
            pos_ptr = strchr(GetInitPos(), c);
            if (nullptr == pos_ptr){
                return false;
            }
            else{
                std::copy(GetInitPos(), pos_ptr, &(*str.begin()));
                MoveReadPos(pos_ptr - GetInitPos());
                return true;
                }   
                return false;
        }
        else{
            std::copy(GetInitPos(), pos_ptr, &(*str.begin()));
            MoveReadPos(pos_ptr - GetInitPos()); 
            return true;
         }
    }
    //清空缓冲区
    void Clear(){
        _read_pos = 0;
        _write_pos = 0;
    }
};

接口介绍

ReadSize:获取缓冲区可读数据的大小

Write:向缓冲区写入数据,第一个参数是从哪里写入,可以是char*   std::string   Buff,第二个参数是写入数据的大小

pry:从缓冲区窥探数据,第一个参数是把数据读到哪里,可以是char*   std::string   Buff,第二个参数是写入数据的大小

Read:从缓冲区读取数据,第一个参数是把数据读到哪里,可以是char*   std::string   Buff,第二个参数是写入数据的大小

ReadLen:从缓冲区读取一行

Clear:清理缓冲区

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2174083.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

巧用枚举消除条件判断

shigen坚持更新文章的博客写手&#xff0c;记录成长&#xff0c;分享认知&#xff0c;留住感动。个人IP&#xff1a;shigen 在上一篇的文章结合HashMap与Java 8的Function和Optional消除ifelse判断中有讲到如何结合HashMap与Java 8的Function和Optional消除ifelse判断&#xff…

校园二手交易平台的小程序+ssm(lw+演示+源码+运行)

摘 要 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和mysql数据库来完成对系统的设计。整个…

Transformer: Attention is all you need

Transformer于2017年提出&#xff0c;最开始应用于NLP领域&#xff0c;随着Transformer的快速发展&#xff0c;在视觉领域中也越来越多的论文或应用用到了Transformer&#xff0c;这里记录一下自己学习的一些知识点。 PDF&#xff1a; 《Attention Is All You Need》 Code: att…

【HTML5】html5开篇基础(3)

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…

带您了解《人工智能机器视觉应用工程师》

人工智能机器视觉应用是指利用人工智能技术和机器视觉技术相结合&#xff0c;使机器能够像人类一样通过视觉感知和理解环境&#xff0c;从而实现各种应用。随着人工智能技术的不断发展&#xff0c;机器视觉应用在各个领域得到了广泛应用。 在工业制造领域&#xff0c;人工智能机…

Unity3D入门(三) : Android和Unity3D交互 - Android调用Unity

1. 前言 上篇文章&#xff0c;我们讲了如何在Unity3D中过渡地切换相机视角。这篇文章&#xff0c;我们来讲一下Unity3D怎么与Android交互。 1.1 unity和Android的三种通信方式 Unity官方提供的接口 : 有一个弊端&#xff0c;它有一个传输内容量的一个限制&#xff0c;传输内…

Java---异常及处理

一.异常 1.概念 程序的非正常执行。高级语言都有异常处理机制&#xff08;C&#xff0c;Java&#xff09; 2.一般处理异常的方法 Scanner sc new Scanner(System.in);System.out.println("请输入一个数字:");String s sc.nextLine();if (s.matches("[0-9]&qu…

数据结构 - 排序算法

一.冒泡排序 /*** description: 冒泡排序* param - a : 要进行排序的数组的指针* param - length : 数组中元素的个数* return : 无 */ void Bubble_sort(int *a,int length) {int temp,i,j;for(i 0;i < length -1;i){for(j…

基于SpringBoot+Vue的小儿推拿培训管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

SSM框架VUE电影售票管理系统开发mysql数据库redis设计java编程计算机网页源码maven项目

一、源码特点 smm VUE电影售票管理系统是一套完善的完整信息管理类型系统&#xff0c;结合SSM框架和VUE、redis完成本系统&#xff0c;对理解vue java编程开发语言有帮助系统采用ssm框架&#xff08;MVC模式开发&#xff09;&#xff0c;系 统具有完整的源代码和数据库&#…

Vue devtools 插件

一、安装 去这下载https://chrome.zzzmh.cn/ 打开chrome的扩展程序 再打开开发模式 把刚才下载的拖到这里 然后把它固定到工具栏 就是这样了。 二、使用 程序通过open on live server后&#xff0c;打开开发者工具&#xff0c;找到vue就可以了。 这是代码 <div id"ap…

C++ 基础入门-命名空间、c++的输入输出、缺省参数、函数重载、引用、内联函数超详细讲解

这篇文章主要对c的学习做一个基础铺垫&#xff0c;方便后续学习。主要通过示例讲解命名空间、c的输入输出cout\cin&#xff0c;缺省参数、函数重载、引用、内联函数&#xff0c;auto关键字&#xff0c;for循环&#xff0c;nullptr以及涉及到的周边知识&#xff0c;面试题等。为…

遍历递归数结构,修改里的disabled值

返回参数中新增字段 disabled,后端给的值为1和2, disabled1时&#xff0c;代表该节点需要置灰&#xff0c;不可选中 现在需要将disabled的值,改为布尔类型; 后端给的数结构是对象类型,tree接收数组类型; 先将对象类型的数据,遍历递归,修改里面的disabled值,最后再加[ ],改为…

Magnific推V2图像生成服务 可直出4K图像

人工智能 - Ai工具集 - 集合全球ai人工智能软件的工具箱网站 近日&#xff0c;AI图像处理领域再迎重大突破&#xff0c;Magnific推出的V2图像生成服务引领行业潮流。此次升级&#xff0c;不仅使Magnific从高端软件跻身为顶级AI图像生成器&#xff0c;更彰显了其在技术创新及用…

html+css+js实现Progress 进度条

实现效果 代码实现 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>progress</title><st…

动手学深度学习(李沐)PyTorch 第 4 章 多层感知机

4.1 多层感知机 隐藏层 我们在 3.1.1.1节中描述了仿射变换&#xff0c; 它是一种带有偏置项的线性变换。 首先&#xff0c;回想一下如 图3.4.1中所示的softmax回归的模型架构。 该模型通过单个仿射变换将我们的输入直接映射到输出&#xff0c;然后进行softmax操作。 如果我们…

5V继电器模块详解(STM32)

目录 一、介绍 二、模块原理 1.原理图 2.引脚描述 3.工作原理介绍 三、程序设计 main.c文件 relay.h文件 relay.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 继电器(Relay)&#xff0c;也称电驿&#xff0c;是一种电子控制器件&#xff0c;它具有控制系统…

力扣75道热门算法题 第一天

1768、交替合并字符串 题解&#xff1a; class Solution {public String mergeAlternately(String word1, String word2) {int m word1.length(),n word2.length();int i 0, j 0; //双指针遍历两个数组StringBuilder sb new StringBuilder(); //生成一个StringBuilder对象…

如何禁止电脑上某个软件运行?电脑设置禁止运行软件的4个方法速成

在日常使用电脑的过程中&#xff0c;可能会遇到需要禁止某些软件运行的情况。 无论是为了防止员工随意使用与工作无关的软件&#xff0c;还是为了管理孩子的电脑使用时间&#xff0c;禁止特定软件运行都是有效的解决方案。 下面介绍4个速成方法&#xff0c;帮你轻松禁止电脑上…

AlmaLinux 9 安装mysql8.0.38

文件下载 https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.39-linux-glibc2.12-x86_64.tar 选择合适系统版本 下载后解压 tar -xvf mysql-8.0.39-linux-glibc2.12-x86_64.tar解压后里面有三个文件夹 使用mysql-8.0.39-linux-glibc2.12-x86_64.tar.xz即可&#xff0c…