Хорошо, вы заставляете меня догадываться о настоящем вопросе.
Но я составил несколько тестовых случаев с «говорящими» запасными значениями. Я использую карму для форматирования результата разбора. Для правильной оценки (на самом деле, проверяя мое здравомыслие) я предоставил результаты тестов как с прямым порядком байтов, так и с байтовым порядком байтов.
Надеюсь, это поможет:
Код
#include <boost/fusion/adapted.hpp>
#include <boost/tuple/tuple_io.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace karma = boost::spirit::karma;
namespace phx = boost::phoenix;
template <typename dword_t, typename qword_t, typename Cases>
void test(const dword_t& dword, const qword_t& qword, const Cases& cases)
{
typedef boost::tuple<uint32_t,uint32_t,uint32_t,uint64_t> attr_t;
typedef const char* Iterator;
int count = 0;
for (auto testcase : cases)
{
Iterator f = reinterpret_cast<const char*>(&*testcase.begin());
Iterator l = reinterpret_cast<const char*>(&*testcase.end());
Iterator b = f;
qi::rule<Iterator, attr_t(), qi::locals<uint32_t> > r;
r %= dword [ qi::_a = qi::_1 ]
>> (( qi::eps(qi::_a & 0x01ul) > dword) | qi::attr(0x0123ul ))
>> (( qi::eps(qi::_a & 0x10ul) > dword) | qi::attr(0x0234ul ))
>> (( qi::eps(qi::_a & 0x80ul) > qword) | qi::attr(0x0345ull))
;
attr_t data;
bool ok = qi::parse(f,l,r,data);
std::cout << std::dec << "testcase " << count++ << "\t"
<< "success: " << std::boolalpha << ok << "\t"
<< "parsed: " << std::distance(b, f) << (f==l?"(complete)\n":"(incomplete)\n")
<< "\t" << std::hex << data << "\n";
}
}
typedef std::vector<uint32_t> Input;
int main()
{
std::cout << "little endian: ";
test(qi::dword, qi::qword, std::list<Input> {
{ 0x11110000u, 0x22220000u, 0x44440000u, 0x88880000u, 0x99990000u, },
{ 0x11110001u, 0x22220000u, 0x44440000u, 0x88880000u, 0x99990000u, },
{ 0x11110010u, 0x22220000u, 0x44440000u, 0x88880000u, 0x99990000u, },
{ 0x11110080u, 0x22220000u, 0x44440000u, 0x88880000u, 0x99990000u, },
{ 0x11110011u, 0x22220000u, 0x44440000u, 0x88880000u, 0x99990000u, },
{ 0x11110081u, 0x22220000u, 0x44440000u, 0x88880000u, 0x99990000u, },
{ 0x11110091u, 0x22220000u, 0x44440000u, 0x88880000u, 0x99990000u, },
});
std::cout << "\nbig endian: ";
test(qi::big_dword, qi::big_qword, std::list<Input> {
{ 0x00001111u, 0x00002222u, 0x00004444u, 0x00008888u, 0x00009999u, },
{ 0x01001111u, 0x00002222u, 0x00004444u, 0x00008888u, 0x00009999u, },
{ 0x10001111u, 0x00002222u, 0x00004444u, 0x00008888u, 0x00009999u, },
{ 0x80001111u, 0x00002222u, 0x00004444u, 0x00008888u, 0x00009999u, },
{ 0x11001111u, 0x00002222u, 0x00004444u, 0x00008888u, 0x00009999u, },
{ 0x81001111u, 0x00002222u, 0x00004444u, 0x00008888u, 0x00009999u, },
{ 0x91001111u, 0x00002222u, 0x00004444u, 0x00008888u, 0x00009999u, },
});
}
выход
little endian: testcase 0 success: true parsed: 4(incomplete)
(11110000 123 234 345)
testcase 1 success: true parsed: 8(incomplete)
(11110001 22220000 234 345)
testcase 2 success: true parsed: 8(incomplete)
(11110010 123 22220000 345)
testcase 3 success: true parsed: 12(incomplete)
(11110080 123 234 4444000022220000)
testcase 4 success: true parsed: 12(incomplete)
(11110011 22220000 44440000 345)
testcase 5 success: true parsed: 16(incomplete)
(11110081 22220000 234 8888000044440000)
testcase 6 success: true parsed: 20(complete)
(11110091 22220000 44440000 9999000088880000)
big endian: testcase 0 success: true parsed: 4(incomplete)
(11110000 123 234 345)
testcase 1 success: true parsed: 8(incomplete)
(11110001 22220000 234 345)
testcase 2 success: true parsed: 8(incomplete)
(11110010 123 22220000 345)
testcase 3 success: true parsed: 12(incomplete)
(11110080 123 234 2222000044440000)
testcase 4 success: true parsed: 12(incomplete)
(11110011 22220000 44440000 345)
testcase 5 success: true parsed: 16(incomplete)
(11110081 22220000 234 4444000088880000)
testcase 6 success: true parsed: 20(complete)
(11110091 22220000 44440000 8888000099990000)