views:

133

answers:

2

Recently, I try to use the boost::spirit::qi binary endian parser to parse some binary data depends on the endianness of the Platform. There is a simple example, like following:

Using declarations and variables:

using boost::spirit::qi::little_word;
using boost::spirit::qi::little_dword;
using boost::spirit::qi::little_qword;

boost::uint16_t us;
boost::uint32_t ui;
boost::uint64_t ul;

Basic usage of the little endian binary parsers:

test_parser_attr("\x01\x02", little_word, us); assert(us == 0x0201);
test_parser_attr("\x01\x02\x03\x04", little_dword, ui); assert(ui == 0x04030201);
test_parser_attr("\x01\x02\x03\x04\x05\x06\x07\x08", little_qword, ul);
assert(ul == 0x0807060504030201LL);

test_parser("\x01\x02", little_word(0x0201));
test_parser("\x01\x02\x03\x04", little_dword(0x04030201));
test_parser("\x01\x02\x03\x04\x05\x06\x07\x08",
    little_qword(0x0807060504030201LL));

It works very well. But my questions come, why do we need use some data types like boost::uint16_t, boost::uint32_t here? Can I use unsigned long or unsigned int here? And if I want to parse double or float data type, what boost data type should I use? And please tell me where is boost define the above these types?

Thanks a lot.

+4  A: 

Types like uint16_t or uint32_t exist so that you can declare a variable to have a specific bit width. You can't do this with normal types like "long" because they are different sizes on different architectures and/or implementations. The afore mentioned types are normally derived by through preprocessor calculations resulting in typedefs to the implementation/architectural specific type to get that specific size.

Noah Roberts
Thanks a lot. Does this mean for float type or double type that it is OK to use the float type like the above types, like uint16_t? Because the float is fixed bit size, which represents a single-precision 32-bit IEEE 754 value. Similarly, for the double type.
Hai
I think that you're asking if you can use a uint16_t as a float or a float as a uint16_t? The answer is no. Floating point types and integral types are totally different from each other and are not interchangeable.
Noah Roberts
No, my question is if I need to parse the binary bits into float or double type by using the boost parser I mentioned. What kind type of variable I should define to hold the parsing result? Can I directly use float or double? Or there is somewhat datatype, for example, boost::ufloat or boost::udouble which I must use to avoid the problem you mentioned in your anwser. My guess seems float or double should be fine, because they are fixed size in IEEE standard.
Hai
@Hai. Yes you may directly use `float`.
KitsuneYMG
+2  A: 

The file <boost/cstdint.hpp> contains all of the boost::(u)int(8|16|32|64)_t definitions. This is provided mainly because MSVC does not ship with <cstdint>. On C++ compilers that are also C compilers (like gcc) <boost/cstdint.hpp> just imports <cstdint> into the boost namespace.

see also: stdint.h

KitsuneYMG
Big thanks. I use gcc 4.0 under Mac OS 10.5.8.
Hai