Inserting a byte into a mutli byte type by index

-1

I have found this answer to a similar question where one can extract a byte from a larger type. What I would like to know is what would be the reverse of this procedure by the use of an index value?

To extract a byte from a 32bit type user Pete Wilson gave this:

int a = (the_int >> 24) & 0xff;  // high-order (leftmost) byte: bits 24-31
int b = (the_int >> 16) & 0xff;  // next byte, counting from left: bits 16-23
int c = (the_int >>  8) & 0xff;  // next byte, bits 8-15
int d = the_int         & 0xff;  // low-order byte: bits 0-7

I would like to do the opposite with an index value:

// assume int = 32bit or 4 bytes and unsigned char = 8bit or 1 byte
void insertByte( unsigned char a, unsigned int& value, unsigned idx ) {
    // How to take byte and insert it into the byte position
    // of value at idx where idx is [0-3] from the right
}

Here's an example by value:

unsigned char a = 0x9D;
unsigned int value = 0;

insertByte( a, value, 0 ); // value = 0x0000009D;
insertByte( a, value, 1 ); // value = 0x00009D00;
insertByte( a, value, 2 ); // value = 0x009D0000;
insertByte( a, value, 3 ); // value = 0x9D000000;
// insertByte( a, value, >3 ); // invalid index

Edit

User jamit made a good point with his question in the comments. I think at this moment because this will be the behavior of a constructor to a class template; I want to insert and replace, not insert and shift.

Example:

unsigned int value = 0x01234567;
unsigned char a = 0x9D;
insertByte( a, value, 2 );
// value = 0x019D4567
c++
byte
c++17
logical-operators
asked on Stack Overflow May 17, 2019 by Francis Cugler • edited May 17, 2019 by Francis Cugler

2 Answers

2

Just cast your char to an int and shift it by the required amount of bytes and add it to your value.

void insertByte( unsigned char a, int& value, unsigned int idx ) {
    if(idx > 3)
        return;
    // Clear the value at position idx
    value &= ~(0xff << (idx*8));

    int tmp = a;
    tmp = (tmp << (idx * 8));

    // Set the value at position idx
    value |= tmp; 
}
answered on Stack Overflow May 17, 2019 by user1178830 • edited May 17, 2019 by user1178830
1

To invert what you got from the other answer:

unsigned a = (the_int & 0x00ffffff) | (the_byte << 24);  // set high-order byte: bits 24-31
unsigned b = (the_int & 0xff00ffff) | (the_byte << 16);  // next byte, bits 16-23
unsigned c = (the_int & 0xffff00ff) | (the_byte << 8);   // next byte, bits 8-15
unsigned d = (the_int & 0xffffff00) | (the_byte);        // low-order byte: bits 0-7

The opposite of bitwise-and is bitwise-or, and the opposite of right-shift is left-shift. The remaining complication is to clear any old value in the byte, which is done with new masks. (If you ignore the new masks, this is a left-shift followed by a bitwise-or. Compare that to extracting the bytes with a right-shift followed by a bitwise-and.)

The current revision of user1178830's answer is a more programatic way to accomplish this.

answered on Stack Overflow May 17, 2019 by JaMiT

User contributions licensed under CC BY-SA 3.0