#ifndef __8BYTE_H__ #define __8BYTE_H__ #include #include #ifdef __cplusplus extern "C" { #endif /* Public: Reads a subset of bits into a uint64_t. * * source - the bytes in question. * offset - the starting index of the bit field (beginning from 0). * bit_count - the width of the bit field to extract. * data_is_big_endian - if the data passed in is little endian, set this to false and it * will be flipped before grabbing the bit field. * * Bit fields are positioned according to big-endian bit layout. * * For example, the bit layout of the value "42" (i.e. 00101010 set at position * 14 with length 6 is: * * 000000000000001010100000000000000000000000000000000000000000000 * * and the same value and position but with length 8 is: * * 000000000000000010101000000000000000000000000000000000000000000 * * If the architecture where is code is running is little-endian, the input data * will be swapped before grabbing the bit field. * * Examples * * uint64_t value = get_bitfield(data, 2, 4); * * Returns the value of the requested bit field, right aligned in a uint64_t. */ uint64_t eightbyte_get_bitfield(uint64_t source, const unsigned int offset, const unsigned int bit_count, const bool data_is_big_endian); /* Public: Return a single nibble from the payload, with range checking. * * source - the source payload. * nibble_index - the index of the nibble to retreive. The leftmost nibble is * index 0. * data_is_big_endian - if the data passed in is little endian, set this to false and it * will be flipped before grabbing the bit field. * * Returns the retreived nibble, right aligned in a unsigned int. */ unsigned int eightbyte_get_nibble(const uint64_t source, const unsigned int nibble_index, const bool data_is_big_endian); /* Public: Return a single byte from the payload, with range checking. * * source - the source byte array. * byte_index - the index of the byte to retreive. The leftmost byte is index 0. * data_is_big_endian - if the data passed in is little endian, set this to false and it * will be flipped before grabbing the bit field. * * Returns the retreived byte. */ unsigned int eightbyte_get_byte(const uint64_t source, const unsigned int byte_index, const bool data_is_big_endian); /* Public: Set the bit field in the given data array to the new value. * * destination - a byte array with size at least offset + bit_count. * value - the value to set in the bit field. * offset - the starting index of the bit field (beginning from 0). * bit_count - the number of bits to set in the data. * * Returns true if the bit_count is enough to fully represent the value, and * false if it will not fit. */ bool eightbyte_set_bitfield(uint64_t value, const unsigned int offset, const unsigned int bit_count, uint64_t* destination); /* Private: Determine the index of the last bit used. */ unsigned int find_end_bit(const unsigned int num_bits); #ifdef __cplusplus } #endif #endif // __8BYTE_H__