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

news/2024/5/25 8:59:57/文章来源:https://blog.csdn.net/weixin_67595436/article/details/136490846

目录

类功能

类定义

类实现

编译测试

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.luyixian.cn/news_show_1005654.aspx

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

相关文章

matplotlib系统学习记录

日期&#xff1a;2024.03.12 内容&#xff1a;将matplotlib的常用方法做一个记录&#xff0c;方便后续查找。 基本使用 # demo01 from matplotlib import pyplot as plt # 设置图片大小,也就是画布大小 fig plt.figure(figsize(20,8),dpi80)#图片大小&#xff0c;清晰度# 准…

信息安全与阿里云等保三级方案实践总结

信息安全在当今数字化时代变得至关重要&#xff0c;企业和组织需要采取有效措施来保护其数据和信息资产。阿里云作为中国领先的云服务提供商&#xff0c;提供了等保三级方案&#xff0c;帮助用户满足国家信息安全等级保护的要求。本文将探讨信息安全和阿里云等保三级方案的重要…

PyTorch搭建LeNet训练集详细实现

一、下载训练集 导包 import torch import torchvision import torch.nn as nn from model import LeNet import torch.optim as optim import torchvision.transforms as transforms import matplotlib.pyplot as plt import numpy as npToTensor()函数&#xff1a; 把图像…

大载重无人机基础技术,研发一款50KG负重六旋翼无人机技术及成本分析

六旋翼无人机是一种多旋翼无人机&#xff0c;具有六个旋翼&#xff0c;通常呈“X”形布局。它采用电动串列式结构&#xff0c;具有垂直起降、悬停、前飞、后飞、侧飞、俯仰、翻滚等多种飞行动作的能力。六旋翼无人机通常被用于航拍、农业植保、环境监测、地形测绘等领域。 六旋…

【JavaScript】数据类型转换 ① ( 隐式转换 和 显式转换 | 常用的 数据类型转换 | 转为 字符串类型 方法 )

文章目录 一、 JavaScript 数据类型转换1、数据类型转换2、隐式转换 和 显式转换3、常用的 数据类型转换4、转为 字符串类型 方法 一、 JavaScript 数据类型转换 1、数据类型转换 在 网页端 使用 HTML 表单 和 浏览器输入框 prompt 函数 , 接收的数据 是 字符串类型 变量 , 该…

Linux本地搭建FastDFS系统

文章目录 前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx 2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.…

uniapp封装统一请求(get和post)

uniapp封装请求 request.js文件 import Vue from vue // 全局配置 import settings from ./settings.js function computedBaseUrl(url) {// console.log(url);return (url.indexOf(http) -1 ? settings.baseUrl : ) url }// 发送请求 export default (options) > {const…

1688平台官方开发平台API接口接入|发布商品|订单查询|跨境API接口

《财经十一人》获悉&#xff0c;阿里巴巴&#xff08;BABA.N&#xff09;旗下中国B2B平台1688正布局跨境业务。 举措主要有二&#xff1a;一是提供跨境版API接口&#xff0c;可将1688的货盘导入各类有流量的平台&#xff0c;比如各国代采网站、服务商SaaS&#xff08;软件服务…

30m二级分类土地利用数据Arcgis预处理及获取

本篇以武汉市为例&#xff0c;主要介绍将土地利用数据转换成武汉市内各区土地利用详情的过程以及分区统计每个区内各地类面积情况&#xff0c;后面还有制作过程中遇到的面积制表后数据过小的解决方法以及一些相关的知识点&#xff1a; 示例数据下载链接&#xff1a;数据下载链…

NCDA设计大赛中游戏美术设计命题参赛指南

未来设计师・全国高校数字艺术设计大赛&#xff08;NCDA&#xff09;正在如火如荼的进行中&#xff0c;各个命题单位也在陆续发出自己的参赛要求。不知道大学生们准备得怎么样。相信大家一定都在全网搜索往年的获奖作品&#xff0c; 今天我为大家整理了一些 NCDA 前几年的获奖作…

基于Redis自增实现全局ID生成器(详解)

本博客为个人学习笔记&#xff0c;学习网站与详细见&#xff1a;黑马程序员Redis入门到实战 P48 - P49 目录 全局ID生成器介绍 基于Redis自增实现全局ID 实现代码 全局ID生成器介绍 背景介绍 当用户在抢购商品时&#xff0c;就会生成订单并保存到数据库的某一张表中&#…

鸿蒙视频播放的实现

文章目录 前言播放效果视频播放的实现总结 一、前言 现在市面上很多应用都跟视频有关&#xff0c;那么在鸿蒙系统上怎么来播放视频呢&#xff0c;今天就讲解视频播放控件&#xff0c;让你也能快速地进行视频播放功能开发。 最后呢&#xff0c;我会提供一个鸿蒙中涉及的主要…

系统安全保证措施-word

【系统安全保证措施-各支撑材料直接套用】 一、 身份鉴别 二、 访问控制 三、 通信完整性、保密性 四、 抗抵赖 五、 数据完整性 六、 数据保密性 七、 应用安全支撑系统设计 软件全套资料下载进主页。

数字化转型导师坚鹏:科技创新产业发展研究及科技金融营销创新

科技创新产业发展研究及科技金融营销创新 课程背景&#xff1a; 很多银行存在以下问题&#xff1a; 不清楚科技创新产业的发展现状&#xff1f; 不知道科技金融有哪些成功的案例&#xff1f; 不知道科技金融如何进行营销创新&#xff1f; 课程特色&#xff1a; 以案例…

说说JVM的垃圾回收机制

简介 垃圾回收机制英文为Garbage Collection, 所以我们常常称之为GC。那么为什么我们需要垃圾回收机制呢&#xff1f;如果大家有了解过Java虚拟机运行时区域的组成(JVM运行时存在&#xff0c;本地方法栈&#xff0c;虚拟机方法栈&#xff0c;程序计数器&#xff0c;堆&#xf…

Uni-app跟学笔记(四):图片API、跨端兼容、组件注册、组件通信

文章目录 1&#xff09;图片API1&#xff1a;图片上传2&#xff1a;图片预览 2&#xff09;跨端兼容3&#xff09;导航跳转4&#xff09;组件及其生命周期1&#xff1a;注册组件2&#xff1a;组件生命周期 5&#xff09;组件的通信1&#xff1a;父组件给子组件传值1-父组件2-子…

打造你的HTML5打地鼠游戏:零基础入门教程

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

计算机组成原理实验报告1 | 实验1.1 运算器实验(键盘方式)

本文整理自博主大学本科《计算机组成原理》课程自己完成的实验报告。 —— *实验环境为学校机房实验箱。 目录 一、实验目的 二、实验内容 三、实验步骤及实验结果 Ⅰ、单片机键盘操作方式实验 1、实验连线&#xff08;键盘实验&#xff09; 2、实验过程 四、实验结果的…

CountDownLatch介绍和使用

1. CountDownLatch是什么 CountDownLatch 是 Java.util.concurrent 包中的一个同步工具类&#xff0c;用于控制线程的执行顺序。它的主要作用是让一个或多个线程等待其他线程完成操作后再继续执行。 2. CountDownLatch 类常用方法 CountDownLatch(int count) 是 CountDownLa…

String 底层是如何实现的?

1、典型回答 String 底层是基于数组实现的&#xff0c;并且数组使用了 final 修饰&#xff0c;不同版本中的数组类型也是不同的&#xff1a; JDK9 之前&#xff08;不含JDK9&#xff09; String 类是使用 char[ ]&#xff08;字符数组&#xff09;实现的但 JDK9 之后&#xf…