views:

102

answers:

2

I have an 8 byte message where the differing chunks of the message are mapped to datums of different types (int, bool, etc.), and they vary in bit sizes (an int value is 12 bits in the message, etc.). I want to pass only the bits a datum is concerned with, but I am not sure if there is a better way. My current thoughts is to make a bit array type with a vector back end and have a templated accessor to get the value contained within to the type specified. Although as I am typing this I am starting to think a great big union of all the possible types could be passed to each datum.

EDIT:

The messages contain varying types of data. For example, one message contains an 8-bit int and 5 1-bit bools, while another message contains a 16-bit Timestamped (my own class) and an 8-bit int.

+1  A: 

Are the messages alway of the same format/order? Ie. 12bitsInt|8bitsChar|etc. If so a simple solution would be to set up appropriate bitmasks to grab each particular value. Ie. if the first 12 bits (low order) corresponded to an integer we could do:

__uint64 Message; // Obviously has data in it.
int IntPortion = Message & 0x00000111;

Which will copy the first 12 bits of the Message into the first 12 bits of your integer type. Set up appropriate bit masks for each chunk of the message and proceed. If the message format is not constant... well I would need you to elaborate maybe with an example message. Also the boost library has some nice bit manipulation classes:

Dynamic Bitset

Might be overkill if the format is constant though.

DeusAduro
A: 

Have you looked at using a struct with explicit member sizes? For example, if you have a message where the field sizes are:

  • 1st field is 12 bits
  • 2nd field is 20 bits
  • 3rd field is 4 bits
  • ...

You could define a struct like:

typedef struct {
  unsigned int field_1 : 12;
  unsigned int field_2 : 20;
  unsigned int field_3 : 4;
  /* etc */
} message_t;

Assuming that you have the message in a simple char array, either copy the data into a message_t struct or cast it to a message_t* :-

char buffer[8] = /* however it's populated */
message_t* message_ptr = &buffer;
int field1 = message->field_1;
int field2 = message->field_2;
Dave Rigby