lest shift an u8 array

Hi.
I have an exsiting u8 array in a function (function that get u16 array as argument).
How can i create a new u16 array the starts from 3th byte of an existing array?
(What I've tried to achieve below gives me wrong values).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  
func1(u16 *ptr){
u8 Arr[32];

// Arr gets values
// Now i want to return pointer to u16 array that starts from the 3th byte of 
//Arr array  :  |__|__|__|__|<-- start the new array from this byte

u8 * shifted_Arr = Arr+3; // Is this shifting the new array to start from the 3th place of the old one?

u16 * shifted_Arr_16_bit = (u16*)shifted_Arr;

for (int i=0;i<N;i++){
ptr[i] = shifted_Arr_16_bit [i];
}

}
int main() {
u16 buffer[N];

func(buffer);


}


Thanks!
Last edited on
Something like this?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void u8_to_u16(const uint8_t *src, uint16_t *dst, const size_t len)
{
    size_t pos = 0U;
    for(size_t i = 0U; i < len; ++i)
    {
        if (!(i & 0x1))
        {
            dst[pos] = ((uint16_t)src[i]) << 8; // set the upper byte of the 16-bit word; lower byte is 0x00 for now
        }
        else
        {
            dst[pos++] |= src[i]; // set the lower byte of the 16-bit word, upper byte (set previously) is unchanged
        }
    }
}
Example:
1
2
3
4
5
const uint8_t input[6U] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 };
uint16_t output[3U];
printf("in: %02X, %02X, %02X, %02X, %02X, %02X\n", input[0U], input[1U], input[2U], input[3U], input[4U], input[5U]);
u8_to_u16(input, output, 6U);
printf("out: %04X, %04X, %04X\n", output[0U], output[1U], output[2U]);
Result:
1
2
in: 11, 22, 33, 44, 55, 66
out: 1122, 3344, 5566


Function assumes that dst is large enough to store at least (len + 1) / 2 16-Bit words!

Also the function stores the bytes into the 16-Bit words in "big-endian" order, i.e. first bytes goes into the upper 8 bits of the 16-Bit word, second byte goes into the lower 8 bits of the 16-Bit word. Should be trivial to adapt, if you need "little-endian".

If you want to skip the first n bytes of src, then simply call it like this:
u8_to_u16(src + n, dst, len_of_src - n);

Example:
1
2
3
4
5
const uint8_t input[6U] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 };
uint16_t output[3U];
printf("in: %02X, %02X, %02X, %02X, %02X, %02X\n", input[0U], input[1U], input[2U], input[3U], input[4U], input[5U]);
u8_to_u16(input + 3U, output, 3U);
printf("out: %04X, %04X\n", output[0U], output[1U]/*, output[2U]*/);
Result:
1
2
in: 11, 22, 33, 44, 55, 66
out: 4455, 6600
Last edited on
what you had is probably close.
remember that c++ starts at zero. the THIRD location is [2]
so Arr+3 is the FOURTH location: {first:[0],second:[1],third:[2],fourth:[3]}

and the rest of it looks like it might work, depending on the real code.

messing with bytes directly for ints can get you into byte order problems, so be sure you know which way the bytes are aligned for your needs. it may be easier to code and work with this if you just used integers instead of arrays of bytes -- a pointer into an integer IS an array of bytes if you do it right... but that depends on the bigger picture of what you are doing. a 64 bit int is only 8 bytes, so it may not be enough, but you can shift those in one operation, a lot faster, than doing it byte by byte, and you can copy/move etc in 8 byte blocks as well. But again, it depends.
Last edited on
Topic archived. No new replies allowed.