Util工具类功能设计与类设计(http模块一)

目录

类功能

类定义

类实现

编译测试

Split分割字符串测试

ReadFile读取测试

WriteFile写入测试

UrlEncode编码测试

UrlDecode编码测试

StatuDesc状态码信息获取测试

ExtMime后缀名获取文件mime测试

IsDirectory&IsRegular测试

VaildPath请求路径有效性判断测试

总编译

补充

trunc截断

编码格式的规定

md5sum校验和比较两个文件是否一致

新增gdb调试手法


类功能

类定义

#include "../server.hpp"class Util{public :// 字符串分割函数size_t Split();// 读取文件内容static bool ReadFile();// 向文件写入数据static bool WriteFile();// URL编码static bool UrlEncode();// URL解码static bool UrlDecode();// 响应状态码的描述信息获取static std::string StatuDesc();// 根据文件后缀名获取文件mimestatic std::string ExtMime();// 判断一个文件是否是一个目录static bool IsDirectory();// 判断一个文件是否是一个普通文件static bool IsRegular();// http请求的资源路径有效性判断static bool VaildPath();
};

类实现

#include "../server.hpp"
#include <sys/stat.h>
#include <fstream>class Util
{
public:// 字符串分割函数static size_t Split(const std::string &src, const std::string &sep, std::vector<std::string> *arry){size_t offset = 0;// 有10个字符,offset是查找的起始位置,范围应该是0~9,offset==10就代表已经越界了,返回查找的位置while (offset < src.size()){size_t pos = src.find(sep, offset); // 在src字符串偏移量offset处,开始向后查找sep字符/子串,返回查找到的位置if (pos == std::string::npos)       // 没有找到特定的字符{// 将剩余的部分当做一个子串,放入arry中if (pos == src.size())break;arry->push_back(src.substr(offset));return arry->size();}if (pos == offset){offset = pos + sep.size();continue; // 当前字符串是一个空串,没有内容}arry->push_back(src.substr(offset, pos - offset));offset = pos + sep.size();}return arry->size();}// 读取文件的所有内容,将读取到的内容放到一个容器中static bool ReadFile(const std::string &filename, std::string *buf){std::ifstream ifs(filename, std::ios::binary); // 以二进制的方式读取if (ifs.is_open() == false){printf("OPEN %s FILE FAILED!!", filename.c_str());return false;}size_t fsize = 0;            // 偏移量ifs.seekg(0, ifs.end);       // 跳转读写位置到末尾fsize = ifs.tellg();         // 获取当前读写位置相对于起始位置的偏移量,从末尾偏移量刚好就是文件大小ifs.seekg(0, ifs.beg);       // 跳转到起始位置buf->resize(fsize);          // 开辟文件大小的空间ifs.read(&(*buf)[0], fsize); // c_str()返回的是一个const,所以不行if (ifs.good() == false){printf("READ %s FILE FAILED!!", filename.c_str());ifs.close();return false;}ifs.close();return true;}// 向文件写入数据static bool WriteFile(const std::string &filename, const std::string &buf){std::ofstream ofs(filename, std::ios::binary | std::ios::trunc);if (ofs.is_open() == false){printf("OPEN %s FILE FAILED!!", filename.c_str());return false;}ofs.write(buf.c_str(), buf.size());if (ofs.good() == false){ERR_LOG("WRITE %s FILE FAILED!", filename.c_str());ofs.close();return false;}ofs.close();return true;}// URL编码,避免URL中资源路径与查询字符串中的特殊字符与HTTP请求中特殊字符产生歧义// 编码格式:将特殊字符的ascii值,转换为两个16进制字符,前缀%   C++ -> C%2B%2B// 不编码的特殊字符: RFC3986文档规定 . - _ ~ 字母,数字属于绝对不编码字符// RFC3986文档规定,编码格式 %HH// W3C标准中规定,查询字符串中的空格,需要编码为+, 解码则是+转空格static std::string UrlEncode(const std::string url, bool convert_space_to_plus){std::string res;for (auto &c : url){if (c == '.' || c == '-' || c == '_' || c == '~' || isalnum(c)){res += c;continue;}if (c == ' ' && convert_space_to_plus == true){res += '+';continue;}// 剩下的字符都是需要编码成为 %HH 格式char tmp[4] = {0};// snprintf 与 printf比较类似,都是格式化字符串,只不过一个是打印,一个是放到一块空间中snprintf(tmp, 4, "%%%02X", c);res += tmp;}return res;}static char HEXTOI(char c){if (c >= '0' && c <= '9')return c - '0';else if (c >= 'a' && c <= 'z')return c - 'a' + 10; // 注意要加10,16进制中,字母a从11开始else if (c >= 'A' && c <= 'Z')return c - 'A' + 10;return -1;}// URL解码static std::string UrlDecode(const std::string url, bool convert_plus_to_space){// 遇到了%,则将紧随其后的2个字符,转换为数字,第一个数字左移4位,然后加上第二个数字//  + ->2b  %2b->2 << 4 + 11std::string res;for (int i = 0; i < url.size(); i++){if (url[i] == '+' && convert_plus_to_space == true){res += ' ';continue;}if (url[i] == '%'){char v1 = HEXTOI(url[i + 1]);char v2 = HEXTOI(url[i + 2]);char v = v1 * 16 + v2;i += 2;continue;}res += url[i];}return res;}// 响应状态码的描述信息获取static std::string StatuDesc(int statu){std::unordered_map<int, std::string> _statu_msg = {{100, "Continue"},{101, "Switching Protocol"},{102, "Processing"},{103, "Early Hints"},{200, "OK"},{201, "Created"},{202, "Accepted"},{203, "Non-Authoritative Information"},{204, "No Content"},{205, "Reset Content"},{206, "Partial Content"},{207, "Multi-Status"},{208, "Already Reported"},{226, "IM Used"},{300, "Multiple Choice"},{301, "Moved Permanently"},{302, "Found"},{303, "See Other"},{304, "Not Modified"},{305, "Use Proxy"},{306, "unused"},{307, "Temporary Redirect"},{308, "Permanent Redirect"},{400, "Bad Request"},{401, "Unauthorized"},{402, "Payment Required"},{403, "Forbidden"},{404, "Not Found"},{405, "Method Not Allowed"},{406, "Not Acceptable"},{407, "Proxy Authentication Required"},{408, "Request Timeout"},{409, "Conflict"},{410, "Gone"},{411, "Length Required"},{412, "Precondition Failed"},{413, "Payload Too Large"},{414, "URI Too Long"},{415, "Unsupported Media Type"},{416, "Range Not Satisfiable"},{417, "Expectation Failed"},{418, "I'm a teapot"},{421, "Misdirected Request"},{422, "Unprocessable Entity"},{423, "Locked"},{424, "Failed Dependency"},{425, "Too Early"},{426, "Upgrade Required"},{428, "Precondition Required"},{429, "Too Many Requests"},{431, "Request Header Fields Too Large"},{451, "Unavailable For Legal Reasons"},{501, "Not Implemented"},{502, "Bad Gateway"},{503, "Service Unavailable"},{504, "Gateway Timeout"},{505, "HTTP Version Not Supported"},{506, "Variant Also Negotiates"},{507, "Insufficient Storage"},{508, "Loop Detected"},{510, "Not Extended"},{511, "Network Authentication Required"}};auto it = _statu_msg.find(statu);if (it != _statu_msg.end()){return it->second;}return "Unknow";}// 根据文件后缀名获取文件mimestatic std::string ExtMime(const std::string &filename){std::unordered_map<std::string, std::string> _mime_msg = {{".aac", "audio/aac"},{".abw", "application/x-abiword"},{".arc", "application/x-freearc"},{".avi", "video/x-msvideo"},{".azw", "application/vnd.amazon.ebook"},{".bin", "application/octet-stream"},{".bmp", "image/bmp"},{".bz", "application/x-bzip"},{".bz2", "application/x-bzip2"},{".csh", "application/x-csh"},{".css", "text/css"},{".csv", "text/csv"},{".doc", "application/msword"},{".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},{".eot", "application/vnd.ms-fontobject"},{".epub", "application/epub+zip"},{".gif", "image/gif"},{".htm", "text/html"},{".html", "text/html"},{".ico", "image/vnd.microsoft.icon"},{".ics", "text/calendar"},{".jar", "application/java-archive"},{".jpeg", "image/jpeg"},{".jpg", "image/jpeg"},{".js", "text/javascript"},{".json", "application/json"},{".jsonld", "application/ld+json"},{".mid", "audio/midi"},{".midi", "audio/x-midi"},{".mjs", "text/javascript"},{".mp3", "audio/mpeg"},{".mpeg", "video/mpeg"},{".mpkg", "application/vnd.apple.installer+xml"},{".odp", "application/vnd.oasis.opendocument.presentation"},{".ods", "application/vnd.oasis.opendocument.spreadsheet"},{".odt", "application/vnd.oasis.opendocument.text"},{".oga", "audio/ogg"},{".ogv", "video/ogg"},{".ogx", "application/ogg"},{".otf", "font/otf"},{".png", "image/png"},{".pdf", "application/pdf"},{".ppt", "application/vnd.ms-powerpoint"},{".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},{".rar", "application/x-rar-compressed"},{".rtf", "application/rtf"},{".sh", "application/x-sh"},{".svg", "image/svg+xml"},{".swf", "application/x-shockwave-flash"},{".tar", "application/x-tar"},{".tif", "image/tiff"},{".tiff", "image/tiff"},{".ttf", "font/ttf"},{".txt", "text/plain"},{".vsd", "application/vnd.visio"},{".wav", "audio/wav"},{".weba", "audio/webm"},{".webm", "video/webm"},{".webp", "image/webp"},{".woff", "font/woff"},{".woff2", "font/woff2"},{".xhtml", "application/xhtml+xml"},{".xls", "application/vnd.ms-excel"},{".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},{".xml", "application/xml"},{".xul", "application/vnd.mozilla.xul+xml"},{".zip", "application/zip"},{".3gp", "video/3gpp"},{".3g2", "video/3gpp2"},{".7z", "application/x-7z-compressed"},};// a.b.txt 获取文件名size_t pos = filename.find_last_of('.');if (pos != std::string::npos)return "application/octet-stream"; // 没找着,表示文件是一个二进制文件// 根据扩展名,获取mimestd::string ext = filename.substr(pos);auto it = _mime_msg.find(ext);if (it == _mime_msg.end())return "application/octet-stream";return it->second;}// 判断一个文件是否是一个目录static bool IsDirectory(const std::string &filename){struct stat st;int ret = stat(filename.c_str(), &st);if (ret < 0)return false;return S_ISDIR(st.st_mode);}// 判断一个文件是否是一个普通文件static bool IsRegular(const std::string &filename){struct stat st;int ret = stat(filename.c_str(), &st);if (ret < 0)return false;return S_ISREG(st.st_mode);}// http请求的资源路径有效性判断// /index.html  --- 前边的/叫做相对根目录  映射的是某个服务器上的子目录// 想表达的意思就是,客户端只能请求相对根目录中的资源,其他地方的资源都不予理会// /../login, 这个路径中的..会让路径的查找跑到相对根目录之外,这是不合理的,不安全的static bool VaildPath();
};

编译测试

各个函数依次测试功能

Split分割字符串测试

ReadFile读取测试

WriteFile写入测试

UrlEncode编码测试

UrlDecode编码测试

StatuDesc状态码信息获取测试

ExtMime后缀名获取文件mime测试

IsDirectory&IsRegular测试

VaildPath请求路径有效性判断测试

总编译

无异常,符合预期

测试案例代码

int main()
{std::cout << VaildPath("/html/../../index.html") << std::endl;/*测试(IsDirectory)&(IsRegular)std::cout << IsRegular("../regex/regex.cpp") << std::endl;std::cout << IsRegular("../regex") << std::endl;std::cout << IsDirectory("../regex/regex.cpp") << std::endl;std::cout << IsDirectory("../regex") << std::endl;*//*测试(StatuDesc)&(ExtMime)std::cout << StatuDesc(200) << std::endl;std::cout << ExtMime("a.png") << std::endl;*//*测试(UrlEncode)&(UrlDecode)std::string str = "C  ";std::string res = UrlEncode(str, false);std::string tmp = UrlDecode(res, false);std::cout << "[" << res << "]\n";std::cout << "[" << tmp << "]\n";*//*测试(UrlEncode)std::string str = "/login?user=qingfengyugu&passwwd=C++";std::string res = UrlEncode(str, false);std::cout << res << std::endl;*//*测试(ReadFile)&(ReadFile)std::string buf;bool ret = ReadFile("../eventfd/eventfd.c", &buf);if (ret == false)return false;ret = WriteFile("./ttt.c", buf);if (ret == false)return false;*//*测试(Split)std::string str = "abc,,,";std::vector<std::string> arry;Split(str, ",", &arry);for (auto &s : arry){std::cout << "[" << s << "]\n";}*/return 0;
}

补充

trunc截断

参考文献

c++ 输入输出流  ios::out 和ios::trunc有什么区别-CSDN博客

编码格式的规定

md5sum校验和比较两个文件是否一致

参考文献

Linux下使用md5sum计算和检验MD5码 - 知乎 (zhihu.com)

新增gdb调试手法

建议参考文献

GDB调试run和start的区别_gdb start-CSDN博客

gdb 的 s 和 si 指令有什么区别 - CSDN文库

详解gdb常用指令 | CS笔记 (pynote.net)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IPSEC VPPN实验

实验背景&#xff1a;FW1和FW2是双机热备的状态。 实验要求&#xff1a;在FW和FW3之间建立一条IPSEC通道&#xff0c;保证10.0.2.0/24网段可以正常访问到192.168.1.0/24 IPSEC VPPN实验配置&#xff08;由于是双机热备状态&#xff0c;所以FW1和FW2只需要配置FW1主设备即可&…

docker学习进阶

一、dockerfile解析 官方文档&#xff1a; Dockerfile reference | Docker Docs 1.1、dockfile是什么&#xff1f; dockerfile是用来构建docker镜像的文本文件&#xff0c;由一条条构建镜像所需的指令和参数构成的脚本。 之前我们介绍过通过具体容器反射构建镜像(docker comm…

数据库系统概念(第一周)

⚽前言 &#x1f3d0;四个基本概念 一、数据 定义 种类 特点 二、数据库 三、数据库管理系统&#xff08;DBMS&#xff09; 四、 数据库系统&#xff08;DBS&#xff09; &#x1f3c0;数据库系统和文件系统对比 文件系统的弊端 &#x1f94e;数据视图 数据抽象 …

【uniapp】uniapp小程序中实现拍照同时打开闪光灯的功能,拍照闪光灯实现

一、需求前提 特殊场景中&#xff0c;需要拍照的同时打开闪光灯&#xff0c;&#xff08;例如黑暗场景下的设备维护巡检功能&#xff09;。 起初我是用的uviewui中的u-upload组件自带的拍照功能&#xff0c;但是这个不支持拍照时打开闪光灯&#xff0c;也不支持从通知栏中打开…

Svg Flow Editor 原生svg流程图编辑器(一)

系列文章 Svg Flow Editor 原生svg流程图编辑器&#xff08;二&#xff09; 效果展示 项目概述 svg flow editor 是一款流程图编辑器&#xff0c;提供了一系列流程图交互、编辑所必需的功能&#xff0c;支持前端研发自定义开发各种逻辑编排场景&#xff0c;如流程图、ER 图、…

JavaEE企业开发新技术

目录 2.1 Class对象基本概念 1、概念 2.2 Class对象的获取方式 2.3基本数据类型的Class对象 1、概念 2.4 反射的基本概念 概念 2.5 Class对象的基本使用-1 2.6 Class对象的基本使用-2 newInstance()和new()区别&#xff1a; 2.1 Class对象基本概念 1、概念 反射的…

ubuntu22.01安装及配置

前言 本次安装基于VMware Pro 16进行安装。 ubuntu版本&#xff1a;ubuntu-22.04.3-live-server-amd64.iso 1、下载 1.1官网下载 https://ubuntu.com/download 1.2、清华大学镜像网站下载 https://mirrors.tuna.tsinghua.edu.cn/ 进入网站后搜索ubuntu&#xff0c;选择ubu…

初阶数据结构之---二叉树的顺序结构-堆

引言 今天要讲的堆&#xff0c;不是操作系统虚拟进程地址空间中&#xff08;malloc&#xff0c;realloc等开空间的位置&#xff09;的那个堆&#xff0c;而是数据结构中的堆&#xff0c;它们虽然名字相同&#xff0c;却是截然不同的两个概念。堆的底层其实是完全二叉树&#x…

AIOPS:Zabbix结合讯飞星火做自动化告警+邮件通知并基于人工智能提供解决方案

目前Zabbix官方已经提供Zabbix+ChatGPT的解决方案 ChatGPT一周年,你充分利用了吗?Zabbix+ChatGPT,轻松化解告警! 但是由于需要魔法等其他因素,比较不稳定,遂决定使用国内模型,这里我挑选的是讯飞星火,基于我之前的文档,在此基础上通过Zabbix的告警脚本实现调用AI模型…

C# OpenCvSharp DNN FreeYOLO 人脸检测

目录 效果 模型信息 项目 代码 下载 C# OpenCvSharp DNN FreeYOLO 人脸检测 效果 模型信息 Inputs ------------------------- name&#xff1a;input tensor&#xff1a;Float[1, 3, 192, 320] --------------------------------------------------------------- Outp…

uniapp富文本编辑-editor-vue2-vue3-wangeditor

前言 除了“微信小程序”&#xff0c;其他小程序想要使用editor组件实现富文本编辑&#xff0c;很难vue3项目 官方组件editor&#xff0c;在初始化时有点麻烦&#xff0c;建议搭配第三方组件wangeditor 写在前面 - editor组件缺少editor-icon.css 内容另存为editor-icon.css…

Java基础-内部类

内部类 引言内部类的共性成员内部类静态内部类非静态内部类 局部内部类匿名内部类内部类的使用场景和好处 引言 Java不仅可以定义变量和方法,还可以定义类. 内部类允许你把一些逻辑相关的类组织在一起,并可以控制内部中类的可见性. 这么看来,内部类就像是代码一种隐藏机制:将类…

Postman(注册,使用,作用)【详解】

目录 一、Postman 1. Postman介绍 2. 安装Postman 3. 注册帐号再使用(可保存测试记录) 4. 创建workspace 5. 测试并保存测试记录 一、Postman postman工具可以发送不同方式的请求,浏览器只能发送get请求(所有用这个工具) 在前后端分离开发模式下&#xff0c;前端技术人员…

SVG 渐变边框在 CSS 中的应用

SVG 渐变边框在 CSS 中的应用 <template><div class"home"><div class"one"><svg width"100%" height"100%"><rect x"2" y"2" width"100%" height"100%" fill&q…

R语言自定义颜色

一、创建颜色梯度&#xff08;渐变色&#xff09; 在绘热图时&#xff0c;需要将数值映射到不同的颜色上&#xff0c;这时就需要一系列的颜色梯度colorRampPalette 函数支持自定义的创建一系列的颜色梯度。 代码示例&#xff1a; library(RColorBrewer)x <- colorRampPal…

SaulLM-7B: A pioneering Large Language Model for Law

SaulLM-7B: A pioneering Large Language Model for Law 相关链接&#xff1a;arxiv 关键字&#xff1a;Large Language Model、Legal Domain、SaulLM-7B、Instructional Fine-tuning、Legal Corpora 摘要 本文中&#xff0c;我们介绍了SaulLM-7B&#xff0c;这是为法律领域量…

【你也能从零基础学会网站开发】Web建站之javascript入门篇 认识JavaScript脚本语言

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享 &#x1f40b; 希望大家多多支持, 我们一起学习和进步&#xff01; &#x1f3c5; 欢迎评论 ❤️点赞&#x1f4ac;评论 &#x1f4c2;收藏 &#x1f4c2;加关注 什么是脚本…

0201安装报错-hbase-大数据学习

1 基础环境简介 linux系统&#xff1a;centos&#xff0c;前置安装&#xff1a;jdk、hadoop、zookeeper&#xff0c;版本如下 软件版本描述centos7linux系统发行版jdk1.8java开发工具集hadoop2.10.0大数据生态基础组件zookeeper3.5.7分布式应用程序协调服务hbase2.4.11分布式…

Neo4j 新手教程 环境安装 基础增删改查 python链接 常用操作 纯新手向

Neo4j安装教程&#x1f680; 目前在学习知识图谱的相关内容&#xff0c;在图数据库中最有名的就是Neo4j,为了降低入门难度&#xff0c;不被网上很多华丽呼哨的Cypher命令吓退&#xff0c;故分享出该文档&#xff0c;为自己手动总结&#xff0c;包括安装环境&#xff0c;增删改查…

server win搭建apache网站服务器+php网站+MY SQL数据库调用电子阅览室

一、适用场景&#xff1a; 1、使用开源的免费数据库Mysql&#xff1b; 2、自己建网站的发布&#xff1b; 3、使用php代码建网站&#xff1b; 4、使用windows server作为服务器&#xff1b; 5、使用apache作为网站服务器。 二、win server 中apache网站服务器搭建 &#xff0…