ipv4_opt.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 214 行
CPP
214 行
/*============================================================================= Copyright (c) 2002-2003 Joel de Guzman http://spirit.sourceforge.net/ Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)=============================================================================*/#include <boost/spirit/include/classic_core.hpp>#include <boost/spirit/include/classic_push_back_actor.hpp>#include <boost/spirit/include/classic_if.hpp>#include <boost/spirit/include/classic_for.hpp>#include <boost/spirit/include/phoenix1.hpp>#include <iostream>#include <string>#include <vector>#include <algorithm>/////////////////////////////////////////////////////////////////////////////////// Please check it out ipv4.cpp sample first!// << See ipv4.cpp sample for details >>//// This is a variation of the ipv4.cpp sample. The original ipv4.cpp code// compiles to 36k on MSVC7.1. Not bad! Yet, we want to shave a little bit// more. Is it possible? Yes! This time, we'll use subrules and just store// the rules in a plain old struct. We are parsing at the char level anyway,// so we know what type of rule we'll need: a plain rule<>. The result: we// shaved off another 20k. Now the code compiles to 16k on MSVC7.1.//// Could we have done better? Yes, but only if only we had typeof! << See// the techniques section of the User's guide >> ... Someday... :-)/////////////////////////////////////////////////////////////////////////////////using namespace std;using namespace BOOST_SPIRIT_CLASSIC_NS;using namespace phoenix;struct ipv4_prefix_data{ char prefix_len, n0, n1, n2, n3; ipv4_prefix_data() : prefix_len(0),n0(0),n1(0),n2(0),n3(0) {}};struct ipv4_data{ char packet_len, header_len; std::string header; std::vector<ipv4_prefix_data> prefixes; ipv4_data() : packet_len(0),header_len(0){}};struct ipv4{ ipv4(ipv4_data& data) : data(data) { start = ( packet = '\xff' >> anychar_p[var(data.packet_len) = arg1] >> payload , payload = anychar_p[var(data.header_len) = arg1] >> for_p(var(i) = 0, var(i) < var(data.header_len), ++var(i)) [ anychar_p[var(data.header) += arg1] ] >> *ipv4_prefix , ipv4_prefix = anychar_p [ var(temp.prefix_len) = arg1, var(temp.n0) = 0, var(temp.n1) = 0, var(temp.n2) = 0, var(temp.n3) = 0 ] >> if_p(var(temp.prefix_len) > 0x00) [ anychar_p[var(temp.n0) = arg1] >> if_p(var(temp.prefix_len) > 0x08) [ anychar_p[var(temp.n1) = arg1] >> if_p(var(temp.prefix_len) > 0x10) [ anychar_p[var(temp.n2) = arg1] >> if_p(var(temp.prefix_len) > 0x18) [ anychar_p[var(temp.n3) = arg1] ] ] ] ] [ push_back_a(data.prefixes, temp) ] ); } int i; ipv4_prefix_data temp; rule<> start; subrule<0> packet; subrule<1> payload; subrule<2> ipv4_prefix; ipv4_data& data;};//////////////////////////////////////////////////////////////////////////////// Main program//////////////////////////////////////////////////////////////////////////////intas_byte(char n){ if (n < 0) return n + 256; return n;}voidprint_prefix(ipv4_prefix_data const& prefix){ cout << "prefix length = " << as_byte(prefix.prefix_len) << endl; cout << "n0 = " << as_byte(prefix.n0) << endl; cout << "n1 = " << as_byte(prefix.n1) << endl; cout << "n2 = " << as_byte(prefix.n2) << endl; cout << "n3 = " << as_byte(prefix.n3) << endl;}voidparse_ipv4(char const* str, unsigned len){ ipv4_data data; ipv4 g(data); parse_info<> info = parse(str, str+len, g.start); if (info.full) { cout << "-------------------------\n"; cout << "Parsing succeeded\n"; cout << "packet length = " << as_byte(data.packet_len) << endl; cout << "header length = " << as_byte(data.header_len) << endl; cout << "header = " << data.header << endl; for_each(data.prefixes.begin(), data.prefixes.end(), print_prefix); cout << "-------------------------\n"; } else { cout << "Parsing failed\n"; cout << "stopped at:"; for (char const* s = info.stop; s != str+len; ++s) cout << static_cast<int>(*s) << endl; }}// Test inputs:// The string in the header is "empty", the prefix list is empty.char const i1[8] ={ 0xff,0x08,0x05, 'e','m','p','t','y'};// The string in the header is "default route", the prefix list// has just one element, 0.0.0.0/0.char const i2[17] ={ 0xff,0x11,0x0d, 'd','e','f','a','u','l','t',' ', 'r','o','u','t','e', 0x00};// The string in the header is "private address space", the prefix list// has the elements 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16.char const i3[32] ={ 0xff,0x20,0x15, 'p','r','i','v','a','t','e',' ', 'a','d','d','r','e','s','s',' ', 's','p','a','c','e', 0x08,0x0a, 0x0c,0xac,0x10, 0x10,0xc0,0xa8};intmain(){ parse_ipv4(i1, sizeof(i1)); parse_ipv4(i2, sizeof(i2)); parse_ipv4(i3, sizeof(i3)); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?