tars源码漫谈第32篇------tc_parsepara.h/tc_parsepara.cpp(http式参数的parse)

2024-02-06 11:08

本文主要是介绍tars源码漫谈第32篇------tc_parsepara.h/tc_parsepara.cpp(http式参数的parse),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

     最近要开发一个需求, 涉及到http参数的处理, 我居然还自己去写string到map和map到string的转换, 当看到tc_parsepara后, 深感痛心, 原来, tars的基础库早就实现了这些功能, 来看一下:

/*** Tencent is pleased to support the open source community by making Tars available.** Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.** Licensed under the BSD 3-Clause License (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at** https://opensource.org/licenses/BSD-3-Clause** Unless required by applicable law or agreed to in writing, software distributed * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License.*/#include "util/tc_parsepara.h"namespace tars
{#define ENCODE_TABLE "=&%\r\n"TC_Parsepara::TC_Parsepara(const string &sParam)
{load(sParam);
}TC_Parsepara::TC_Parsepara(const map<string, string> &mpParam)
{load(mpParam);
}TC_Parsepara::TC_Parsepara(const TC_Parsepara ¶)
{_param = para._param;
}TC_Parsepara &TC_Parsepara::operator=(const TC_Parsepara ¶)
{if(this != ¶){clear();_param = para._param;}return *this;
}bool TC_Parsepara::operator==(const TC_Parsepara ¶)
{return _param == para._param;
}const TC_Parsepara TC_Parsepara::operator+(const TC_Parsepara ¶)
{map<string, string> mpParam;mpParam = _param;mpParam.insert(para._param.begin(), para._param.end());return TC_Parsepara(mpParam);
}TC_Parsepara& TC_Parsepara::operator+=(const TC_Parsepara ¶)
{_param.insert(para._param.begin(), para._param.end());return *this;
}TC_Parsepara::~TC_Parsepara()
{clear();
}void TC_Parsepara::clear()
{_param.clear();
}string TC_Parsepara::encodeMap(const map<string, string> &mpParam) const
{string sParsepara("");map<string, string>::const_iterator it = mpParam.begin();while(it != mpParam.end()){sParsepara += encodestr((*it).first) + "=" + encodestr((*it).second);it++;if(it != mpParam.end()){sParsepara += "&";}}return sParsepara;
}void TC_Parsepara::decodeMap(const string &sParam, map<string, string> &mpParam) const
{int iFlag = 0;char ch1 = '=';char ch2 = '&';string sName;string sValue;string sBuffer;if (sParam.length() == 0){mpParam.clear();return ;}string::size_type pos = 0;while( pos <= sParam.length()){if(sParam[pos] == ch1)                                    //中间分隔符,前面读入是name{sName = decodestr(sBuffer);sBuffer = "";iFlag = 1;}else if(sParam[pos] == ch2 || pos == sParam.length())    //结束符,读入的是值{sValue = decodestr(sBuffer);sBuffer = "";if(sName.length() > 0 && iFlag){mpParam[sName] = decodestr(sValue);iFlag = 0;}}else{sBuffer += sParam[pos];}pos++;}
}void TC_Parsepara::load(const string &sParam)
{clear();decodeMap(sParam, _param);
}void TC_Parsepara::load(const map<string, string> &mpParam)
{_param = mpParam;
}string TC_Parsepara::tostr() const
{return encodeMap(_param);
}string &TC_Parsepara::operator[](const string &sName)
{return _param[sName];
}string TC_Parsepara::getValue(const string &sName) const
{string sValue;map<string, string>::const_iterator it;if((it = _param.find(sName)) != _param.end()){sValue = it->second;}return sValue;
}void TC_Parsepara::setValue(const string &sName, const string &sValue)
{_param[sName] = sValue;
}map<string,string> &TC_Parsepara::toMap()
{return _param;
}const map<string,string> &TC_Parsepara::toMap() const
{return _param;
}void TC_Parsepara::traverse(TC_ParseparaTraverseFunc func,void *pParam)
{map<string, string>::iterator it  = _param.begin();map<string, string>::iterator itEnd  = _param.end();while(it != itEnd){func(it->first, it->second, pParam);++it;}
}char TC_Parsepara::x2c(const string &sWhat)
{register char digit;if(sWhat.length() < 2){return '\0';}digit = (sWhat[0] >= 'A' ? ((sWhat[0] & 0xdf) - 'A')+10 : (sWhat[0] - '0'));digit *= 16;digit += (sWhat[1] >= 'A' ? ((sWhat[1] & 0xdf) - 'A')+10 : (sWhat[1] - '0'));return(digit);
}string TC_Parsepara::decodestr(const string &sParam)
{string sBuffer("");string::size_type pos = 0;while( pos < sParam.length()){if(sParam[pos] == '%'){if (pos >= sParam.length() - 2){break;}sBuffer += x2c(sParam.substr(pos + 1));pos += 3;}else{sBuffer += sParam[pos];pos++;}}return sBuffer;
}string TC_Parsepara::encodestr(const string &sParam)
{string sBuffer("");static char sHexTable[17] = "0123456789ABCDEF";string::size_type pos = 0;while( pos < sParam.length()){if(string(ENCODE_TABLE).find_first_of(sParam[pos]) != string::npos){sBuffer += '%';sBuffer += sHexTable[(sParam[pos]>>4)&0x0f];sBuffer += sHexTable[sParam[pos]&0x0f];}else{sBuffer += sParam[pos];}pos++;}return sBuffer;
}}

        简单测试玩了一下, 非常好用。 上述类中函数相当简单, 一看就懂, 无非就是字符串的变换而已, 不需要多说。

 

 

这篇关于tars源码漫谈第32篇------tc_parsepara.h/tc_parsepara.cpp(http式参数的parse)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/684121

相关文章

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

SpringBoot 获取请求参数的常用注解及用法

《SpringBoot获取请求参数的常用注解及用法》SpringBoot通过@RequestParam、@PathVariable等注解支持从HTTP请求中获取参数,涵盖查询、路径、请求体、头、C... 目录SpringBoot 提供了多种注解来方便地从 HTTP 请求中获取参数以下是主要的注解及其用法:1

HTTP 与 SpringBoot 参数提交与接收协议方式

《HTTP与SpringBoot参数提交与接收协议方式》HTTP参数提交方式包括URL查询、表单、JSON/XML、路径变量、头部、Cookie、GraphQL、WebSocket和SSE,依据... 目录HTTP 协议支持多种参数提交方式,主要取决于请求方法(Method)和内容类型(Content-Ty

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

使用Python的requests库来发送HTTP请求的操作指南

《使用Python的requests库来发送HTTP请求的操作指南》使用Python的requests库发送HTTP请求是非常简单和直观的,requests库提供了丰富的API,可以发送各种类型的HT... 目录前言1. 安装 requests 库2. 发送 GET 请求3. 发送 POST 请求4. 发送

python中的显式声明类型参数使用方式

《python中的显式声明类型参数使用方式》文章探讨了Python3.10+版本中类型注解的使用,指出FastAPI官方示例强调显式声明参数类型,通过|操作符替代Union/Optional,可提升代... 目录背景python函数显式声明的类型汇总基本类型集合类型Optional and Union(py

Go语言使用Gin处理路由参数和查询参数

《Go语言使用Gin处理路由参数和查询参数》在WebAPI开发中,处理路由参数(PathParameter)和查询参数(QueryParameter)是非常常见的需求,下面我们就来看看Go语言... 目录一、路由参数 vs 查询参数二、Gin 获取路由参数和查询参数三、示例代码四、运行与测试1. 测试编程路

Go语言使用net/http构建一个RESTful API的示例代码

《Go语言使用net/http构建一个RESTfulAPI的示例代码》Go的标准库net/http提供了构建Web服务所需的强大功能,虽然众多第三方框架(如Gin、Echo)已经封装了很多功能,但... 目录引言一、什么是 RESTful API?二、实战目标:用户信息管理 API三、代码实现1. 用户数据

Python WSGI HTTP服务器Gunicorn使用详解

《PythonWSGIHTTP服务器Gunicorn使用详解》Gunicorn是Python的WSGI服务器,用于部署Flask/Django应用,性能高且稳定,支持多Worker类型与配置,可处... 目录一、什么是 Gunicorn?二、为什么需要Gunicorn?三、安装Gunicorn四、基本使用启

Python lambda函数(匿名函数)、参数类型与递归全解析

《Pythonlambda函数(匿名函数)、参数类型与递归全解析》本文详解Python中lambda匿名函数、灵活参数类型和递归函数三大进阶特性,分别介绍其定义、应用场景及注意事项,助力编写简洁高效... 目录一、lambda 匿名函数:简洁的单行函数1. lambda 的定义与基本用法2. lambda