1

In C, if I want to modify the most significant byte of an integer, I can do it in two different ways:

#include <stdint.h>
#include <stdio.h>

int main() {
    uint32_t i1 = 0xDDDDDDDD;
    printf("i1 original: 0x%X\n", i1);
    uint32_t i1msb = 0xAA000000;
    uint32_t i1_mask = 0x00FFFFFF;
    uint32_t i1msb_mask = 0xFF000000;
    i1 = (i1 & i1_mask) | (i1msb & i1msb_mask);
    printf("i1 modified: 0x%X\n", i1);

    uint32_t i2 = 0xDDDDDDDD;
    printf("i2 original: 0x%X\n", i2);
    uint32_t *i2ptr = &i2;
    char *c2ptr = (char *) i2ptr;
    c2ptr += 3;
    *c2ptr = 0xAA;
    printf("i2 modified: 0x%X\n", i2);
}
i1 original: 0xDDDDDDDD
i1 modified: 0xAADDDDDD
i2 original: 0xDDDDDDDD
i2 modified: 0xAADDDDDD

The masking approach works in both C and Rust, but I don't have not found any way to do the direct byte manipulation approach in (safe) Rust. Although it has some endianness issues that masking does not, I think these can all be resolved at compile time to provide a safe, cross-platform interface, so why is direct byte manipulation not allowed in safe Rust? Or if it is, please correct me as I have been unable to find a function for it - I am thinking something like

fn change_byte(i: &u32, byte_num: usize, new_val: u8) -> Result<(), ErrorType> { ... }

which checks that byte_num is within range before performing the operation, and in which byte_num always goes from least significant byte to most significant.

Agent 008
  • 141
  • 8

1 Answers1

0

Rust doesn't have a function to modify bytes directly. It does, however, have methods to convert integers to byte arrays, and byte arrays to integers. For example, one might write

fn set_low_byte(number:u32, byte:u8)->u32{
  let mut arr = number.to_be_bytes();
  arr[3] = byte;
  u32::from_be_bytes(arr)
}

There are also methods for little and native endian byte order. The bitmask approach is also perfectly doable, and the pointer stuff will also work if you don't mind unsafe.

playground link

Aiden4
  • 2,504
  • 1
  • 7
  • 24