Demultiplex binaries in rust


#1

In C you can do things like this:

typedef struct {
    union {
        unsigned int w0;
        struct {
            unsigned int arg0:24;
            unsigned int cmd:8;
        };
    };
    unsigned int w1;
} Gwords;

This allow nice representation of binary infos:

Gwords* w = (Gwords*)&cmd;

int arg = w->arg0;
int cmd = w->cmd;

Here is a simple example with int but you can have quite longer representations.

  1. How can I achieve this in rust?
  2. The above method is not the most efficient one from performance stand point, what would be the efficient way to “demultiplex” binaries in rust?

Thanks in advance! :slight_smile:


#2

You can, but that is non-portable code relying on implementation-defined details, and IMHO very bad style. If you want to send the data over the network or save it into a file, the program will not be able to communicate with another instance of itself built on a arch with different endianness.

Since it relies on architecture details, my guess is: you can not, unless you use raw pointers inside unsafe blocks.

Did you check? You may know that bitfields are often disliked by hackers and often not very optimized by compilers. Now, I did check (gcc 4.9.3-3 x86_64), and this case is lucky: the non-portable solution produces exactly the same code than the portable solution, namely:

unsigned arg = w & 0xFFFFFF;
unsigned cmd = w >> 24;

The exact same solution, of course, works with Rust.


#3

Thanks! I also heard bitfields (that was the name of this method, thanks!) are not well recognized by compiler.

This would be a perfect use of macro right? Would something like be possible?:

u32 arg0, u32 cmd = demux!(w, 24, 8);

And because it’s macro it could be dynamic I should be able to do this no?:

u32 value1, u32 value2, u32 cmd = demux!(w, 14, 10, 8);

I “just” have to write my own macro right? (as you guess, I’m not familiar with macro yet).


#4

Possibly. Remember that macros are bad at counting, so you may have some trouble making masks, but don’t let that discourage you. :smile: I did once implement a horrific macro for this, but it seems to have been lost in time and I can’t find where I posted it. Maybe that’s just for the better…


#5

You can do this equally well from a plain function and it shouldn’t be any slower since rustc can inline it. (But I haven’t measured.)


#6

Thanks all! I was curious! :smile: