Search code examples
cparity

Strip parity bits in C from 8 bits of data followed by 1 parity bit


I have a buffer of bits with 8 bits of data followed by 1 parity bit. This pattern repeats itself. The buffer is currently stored as an array of octets.

Example (p are parity bits):

0001 0001 p000 0100 0p00 0001 00p01 1100 ...

should become

0001 0001 0000 1000 0000 0100 0111 00 ...

Basically, I need to strip of every ninth bit to just obtain the data bits. How can I achieve this?

This is related to another question asked here sometime back.

This is on a 32 bit machine so the solution to the related question may not be applicable. The maximum possible number of bits is 45 i.e. 5 data octets

This is what I have tried so far. I have created a "boolean" array and added the bits into the array based on the the bitset of the octet. I then look at every ninth index of the array and through it away. Then move the remaining array down one index. Then I've got only the data bits left. I was thinking there may be better ways of doing this.


Solution

  • Your idea of having an array of bits is good. Just implement the array of bits by a 32-bit number (buffer).

    To remove a bit from the middle of the buffer:

    void remove_bit(uint32_t* buffer, int* occupancy, int pos)
    {
        assert(*occupancy > 0);
        uint32_t high_half = *buffer >> pos >> 1;
        uint32_t low_half = *buffer << (32 - pos) >> (32 - pos);
        *buffer = high_half | low_half;
        --*occupancy;
    }
    

    To add a byte to the buffer:

    void add_byte(uint32_t* buffer, int* occupancy, uint8_t byte)
    {
        assert(*occupancy <= 24);
        *buffer = (*buffer << 8) | byte;
        *occupancy += 8;
    }
    

    To remove a byte from the buffer:

    uint8_t remove_byte(uint32_t* buffer, int* occupancy)
    {
        uint8_t result = *buffer >> (*occupancy - 8);
        assert(*occupancy >= 8);
        *occupancy -= 8;
        return result;
    }
    

    You will have to arrange the calls so that the buffer never overflows. For example:

    buffer = 0;
    occupancy = 0;
    add_byte(buffer, occupancy, *input++);
    add_byte(buffer, occupancy, *input++);
    remove_bit(buffer, occupancy, 7);
    *output++ = remove_byte(buffer, occupancy);
    add_byte(buffer, occupancy, *input++);
    remove_bit(buffer, occupancy, 6);
    *output++ = remove_byte(buffer, occupancy);
    ... (there are only 6 input bytes, so this should be easy)