0

I am studying how to use boost spirit Qi binary endian parser. I write a small test parser program according to here and basics examples, but it doesn't work proper. It gave me the msg:"Error:no match".

Here is my code.

 
    #include "boost/spirit/include/qi.hpp"
    #include "boost/spirit/include/phoenix_core.hpp"
    #include "boost/spirit/include/phoenix_operator.hpp"
    #include "boost/spirit/include/qi_binary.hpp"  // parsing binary data in various endianness

   template "<"typename P, typename T>
   void binary_parser( char const* input, P const& endian_word_type, 
                       T& voxel, bool  full_match = true)
 {
   using boost::spirit::qi::parse;
   char const* f(input);
   char const* l(f + strlen(f));
   bool result1 = parse(f,l,endian_word_type,voxel);
   bool result2 =((!full_match) || (f ==l));

   if ( result1 && result2) {
       //doing nothing, parsing data is pass to voxel alreay                           
   } else {
            std::cerr << "Error: not match!!" << std::endl;
            exit(1);
   }
}
   typedef boost::uint16_t bs_int16;
   typedef boost::uint32_t bs_int32;

   int main ( int argc, char *argv[] ){
   namespace qi = boost::spirit::qi;
   namespace ascii = boost::spirit::ascii;


   using qi::big_word;
   using qi::big_dword;


   boost::uint32_t ui;

   float uf;

   binary_parser("\x01\x02\x03\x04",big_word,ui); assert(ui=0x01020304);
   binary_parser("\x01\x02\x03\x04",big_word,uf); assert(uf=0x01020304);

   return 0;
}

I almost copy the example, but why this binary parser doesn't work. I use Mac OS 10.5.8 and gcc 4.01 compiler.

hkaiser
  • 11,403
  • 1
  • 30
  • 35
T.T
  • 25
  • 7

2 Answers2

2

The big_word parser matches a big-endian word (16 bits), while big_dword will match what you want (big-endian dword, 32 bits). But I don't think it to be a good idea to use a float as the attribute to the binary parser, you might not get what you expect.

hkaiser
  • 11,403
  • 1
  • 30
  • 35
  • Thank you, you are right. I didn't get what I expect. So should I parse it as unsigned 32bit int first, then static_cast it as float? Or there is any better way to finish this job? Do I need directly swap the bytes for float or double ? – T.T May 21 '10 at 11:14
  • Generally (well, in IEEE-754), float and double are not endian sensitive, their layout is the same on all architectures. If you need to input/output the binary (bit) representation of floats and doubles using Spirit you probably need to do something ugly like: float f; *reinterpret_cast(&f); or some nasty tricks with a union. But now as I think of it, I believe the best solution would be to add bin_float and bin_double parsers/generators to Spirit. Those are currently missing. I might just write an article on the Spirit website about this... – hkaiser May 21 '10 at 13:14
  • You are right. I don't need Spirit to deal with float numbers. I found my answer here. http://stackoverflow.com/questions/1695681/reading-from-and-writing-to-the-middle-of-a-binary-file-in-c-c – T.T May 24 '10 at 14:37
0

I used wrong parse param. I should not use big_word instead of big_dword

sra
  • 23,820
  • 7
  • 55
  • 89
T.T
  • 25
  • 7