data align issue

I am trying to solve problem mentioned in the below link using CPP. Any comments?
https://stackoverflow.com/questions/41229092/java-datastream-alignment
I have no idea how to handle individual bits that are misaligned as shown in example in the below link. Any inputs here?
Last edited on
The "smallest addressable unit", by definition, is a byte.

Hence, a single bit can not be "misaligned". At least not in the usual sense that an object of size N (in bytes!) is correctly "aligned" if and only if that object's base address is an integer multiple of N.

Nonetheless, the bits within a byte may be shifted, so that, for example, the bit that you expected to be the most significant one is now at the "second most significant" bit position. You can "correct" this by performing a bit-shift in the opposite direction - and by stealing the "missing" bit(s) from the neighboring byte.

1
2
3
4
5
6
7
8
9
10
11
12
void fix_shift(uint8_t *array, const size_t length, const size_t shift)
{
    for (size_t i = 0; i < length; ++i)
    {
        array[i] <<= shift; // left-shift the current byte by 'shift' positions
        if (i < length - 1U)
        {
            array[i] |= array[i+1] >> (8U - shift); // steal the upper '8 - shift' bits of the next byte;
                                                    // we shift them to the right, in order to move them to the desired position
        }
    }
}
Last edited on
From your SO link:
 * A data stream contains a binary stream of data in little endian byte
 * format.
 *
 * The binary data can be mis-aligned to byte boundaries.
 * In order to indicate alignment to the consumer, a periodic alignment 
 * synchronisation sequence is output.
 * The alignment sequence is defined as 4 bytes of 0x00 followed by a
 * byte of 0x80.
 *
 * For example, the following stream is mis-aligned by 3 bits and has an
 * alignment sequence followed by the byte values 0x01,0x02,0x03
 *
 * 0x65, 0x50, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x10, 0x18
 *
 * The sequence ends when there's not enough bits left to fill a byte

This is a weird problem. In particular, I don't see what "little endian" has to do with it since it would be impossible to group bytes together unless you knew something about what they represent (e.g., that the data represents 32-bit ints). The example seems to just be interested in extracting the bytes 0x01, 0x02, 0x03 after finding the "alignment sequence". The following does so but is pretty inefficient.

First it finds (at least) 32 zero bits followed by a 1 and 7 more 0's. Then it extracts as many full bytes as it can.

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;

int main()
{
    using Byte = unsigned char;
    vector<Byte> bytes {
        0x65, 0x50, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x10, 0x18
    };
    vector<Byte> data;

    enum {FindSync1, FindSync2, ReadData} state = FindSync1;
    int i = 0;

    for (auto b: bytes)
    {
        for (int j = 8; j--; b <<= 1)
        {
            Byte bit = (b & 0x80) >> 7;
            switch (state)
            {
            case FindSync1:
                if (bit)
                {
                    if (i >= 32) state = FindSync2;
                    i = 0;
                }
                else
                    ++i;
                break;
            case FindSync2:
                if (bit)
                {
                    state = FindSync1;
                    i = 0;
                }
                else if (++i == 7)
                {
                    state = ReadData;
                    i = 0;
                }
                break;
            case ReadData:
                if (i++ % 8 == 0) data.push_back(0);
                data.back() = (data.back() << 1) | bit;
                break;
            }
        }
    }

    if (i % 8 != 0) data.pop_back();

    cout << hex << setfill('0');
    for (auto b: data) cout << "0x" << setw(2) << unsigned(b) << ' ';
    cout << '\n';
}

Topic archived. No new replies allowed.