#include <stdio.h>

unsigned getBitField(const unsigned *array, unsigned bitpos, unsigned width)
{
  // array is an array of unsigned integers
  // bitpos is the LSb of the bit field
  // width is the number of bits in the bit field
  
  const unsigned bitsInUnsigned = 8*sizeof(unsigned);
  unsigned LSw;
  unsigned byteIndex = bitpos / bitsInUnsigned;
  unsigned bitoffset = (bitpos % bitsInUnsigned);
  LSw = array[byteIndex] >> bitoffset;
  if (bitoffset + width > bitsInUnsigned)
  {
    unsigned numBitInMSw = bitoffset + width - bitsInUnsigned;
    unsigned MSw = array[byteIndex+1] & ((1 << numBitInMSw) - 1);
    unsigned numBitInLSw = width - numBitInMSw;
    LSw &= ((1 << numBitInLSw) - 1);
    LSw |= MSw << numBitInLSw;
  }
  return LSw &= ((1 << width) - 1);
}

void setBitField(unsigned *array, unsigned bitpos, unsigned width, unsigned value)
{
  // array is an array of unsigned integers
  // bitpos is the LSb of the bit field
  // width is the number of bits in the bit field
  
  const unsigned bitsInUnsigned = 8*sizeof(unsigned);
  unsigned LSw;
  unsigned byteIndex = bitpos / bitsInUnsigned;
  unsigned bitoffset = (bitpos % bitsInUnsigned);
  value &= (1 << width) - 1;
  unsigned LSwClearMask = ~(((1 << width) - 1) << bitoffset);
  array[byteIndex] &= LSwClearMask;
  array[byteIndex] |= value << bitoffset;
  if (bitoffset + width > bitsInUnsigned)
  {
    unsigned numBitInMSw = bitoffset + width - bitsInUnsigned;
    unsigned numBitInLSw = width - numBitInMSw;
    unsigned MSw = array[byteIndex+1] & ((1 << numBitInMSw) - 1);
    array[byteIndex+1] &= ~((1 << numBitInMSw) - 1);
    array[byteIndex+1] |= value >> numBitInLSw;
  }
}

int main(void)
{
  unsigned array[256];
  
  setBitField(array, 213, 10, 284);
  printf("%u\n", getBitField(array, 213, 10));
  setBitField(array, 203, 10, 999);
  printf("%u\n", getBitField(array, 203, 10));
  setBitField(array, 223, 10, 982);
  printf("%u\n", getBitField(array, 223, 10));
  printf("%u\n", getBitField(array, 213, 10));
  return 0;
}


