boost spirit的简单使用

尝试通过cpp-netlib来做http服务器,但是这个库只能简单的解析http结构,像cookie等结构,都要自己解析,了解到spirit可以通过类似bnf范式格式定义字符串格式并解析。

boost本身有个类似的例子,解析的是通过分号或者&符号分割的键值对字符串,并放到对应的map中去。具体代码可以参照这里。所以基于这个代码,简单的进行修改之后,就能解析http cookie了。

首先,http cookie的格式,定义在rfc6265上。这里定义了服务器发送给浏览器的Set-Cookie头格式,和浏览器发给服务器的Cookie头的BNF范式。这里定义的太复杂,解析的时候没有考虑到这么多字符(特别是排除一些控制字符),大致的代码:

[cce lang=”cpp”]
namespace parser
{
namespace qi = boost::spirit::qi;
typedef std::map<std::string, std::string> pairs_type;
template <typename Iterator>
struct cooke_sequence : qi::grammar<Iterator, pairs_type()> {
qi::rule<Iterator, pairs_type()> query;
qi::rule<Iterator, std::pair<std::string, std::string>()> pair;
qi::rule<Iterator, std::string()> key, value;
cooke_sequence() : cooke_sequence::base_type(query) {
query = pair >> *(qi::lit(';') >> pair);
pair = *qi::lit(' ') >> key >> *qi::lit(' ') >> -('=' >> *qi::lit(' ') >> value >> *qi::lit(' '));
key = qi::char_("a-zA-Z_%") >> *qi::char_("a-zA-Z_0-9%");
value = +(qi::char_ – ';');
}
};
}
[/cce]

这里简化了key和value,特别是value,只要是非分号的,都能解析到value中。使用也非常简单:

[cce lang=”cpp”]
namespace qi = boost::spirit::qi;
parser::cooke_sequence<std::string::const_iterator> p;
parser::pairs_type value;
if(qi::parse(c.begin(), c.end(), p, value)) {
for(auto &entry : value) {
cookies.insert(std::make_pair(entry.first, entry.second));
}
}
[/cce]

直接实例化cooe_sequence,将cookie字符串传入,就可以解析成map,然后再放入到自己的结构体中。这里直接抄了示例中的代码,所以直接使用了map,一般cookie没必要排序,可以直接使用unordered_map,通过hash表存放。

转载自:https://coolex.info/blog/421.html

时间: 2024-10-30 23:39:13

boost spirit的简单使用的相关文章

使用boost::spirit实现的CSV文件解析类

boost::spirit真是不错的说.... #include <iostream>#include <iterator>#include <vector>#include <string>#include <boost/spirit/core.hpp>#include <boost/spirit/iterator/file_iterator.hpp>using namespace std;using namespace boost

C++ boost库spirit使用手册

尝试通过cpp-netlib来做http服务器,但是这个库只能简单的解析http结构,像cookie等结构,都要自己解析,了解到spirit可以通过类似bnf范式格式定义字符串格式并解析. boost本身有个类似的例子,解析的是通过分号或者&符号分割的键值对字符串,并放到对应的map中去.具体代码可以参照这里 http://www.boost.org/doc/libs/1_55_0/libs/spirit/example/qi/key_value_sequence.cpp.所以基于这个代码,简单

boost::asio译文

Christopher Kohlhoff Copyright 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_0.txt文件或从http://www.boost.org/LICENSE_1_0.txt) Boost.Asio是用于网络和低层IO编程的跨平台C++库,为开发者提供了C++环境下稳定的异步模型. 综述 基本原理 应用程序与外界交互的方式有很多,可通过文件,网络,串口或控制台.例如在网络通信中,完成独

boost::thread类

前言 标准C++线程即将到来.预言它将衍生自Boost线程库,现在让我们探索一下Boost线程库. 几年前,用多线程执行程序还是一件非比寻常的事.然而今天互联网应用服务程序普遍使用多线程来提高与多客户链接时的效率:为了达到最大的吞吐量,事务服务器在单独的线程上运行服务程序:GUI应用程序将那些费时,复杂的处理以线程的形式单独运行,以此来保证用户界面能够及时响应用户的操作.这样使用多线程的例子还有很多. 但是C++标准并没有涉及到多线程,这让程序员们开始怀疑是否可能写出多线程的C++程序.尽管不可

浅析Boost智能指针:scoped_ptr shared_ptr weak_ptr_C 语言

一. scoped_ptrboost::scoped_ptr和std::auto_ptr非常类似,是一个简单的智能指针,它能够保证在离开作用域后对象被自动释放.下列代码演示了该指针的基本应用: 复制代码 代码如下: #include <string>#include <iostream>#include <boost/scoped_ptr.hpp> class implementation{public:    ~implementation() { std::cout

C++中输出十六进制形式字符串的教程

前言 在进行 i18n 相关的开发时,经常遇到字符编码转换的错误.这时如果能把相关字符串用十六进制的形式打印出来,例如,"abc" 输出成 "\\x61\\x62\\x63" 这对于 i18n 的除错来说是很有帮助的.Python 里面,只需要使用repr()函数就行了.可在 C++ 中如何做到这点呢? 下面是用 ostream 的格式化功能的一个简单的实现: std::string get_raw_string(std::stringconst& s) {

GPIO

最新版的uhd/host中提供了对GPIO操作的接口,在multi_usrp.cpp中如下定义: void set_gpio_attr(const std::string &bank, const std::string &attr, const boost::uint32_t value, const boost::uint32_t mask, const size_t mboard) { if (_tree->exists(mb_root(mboard) / "gpio

C++ 智能指针详解

来源:http://blog.csdn.net/xt_xiaotian/article/details/5714477 一个智能指针就是一个C++的对象, 这对象的行为像一个指针,但是它却可以在其不需要的时候自动删除.注意这个"其不需要的时候", 这可不是一个精确的定义.这个不需要的时候可以指好多方面:局部变量退出函数作用域.类的对象被析构--.所以boost定义了多个不同的智能指针来管理不同的场景. shared_ptr<T> 内部维护一个引用计数器来判断此指针是不是需要

指针辨析:悬垂指针、哑指针、野指针、智能指针

悬垂指针:   1:提出的原因: 请看下面的代码片段: int *p=NULL; void main() { int i=10;p=&i; cout<<"第一次:*p = "<<*p<<endl; cout<<"第二次:*p = "<<*p<<endl; } int *p=NULL; void fun() {int i=10;p=&i;} void main() { fun();