mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-13 12:33:42 +02:00
git-subtree-dir: src/simplicity git-subtree-split: 86ac0f92c4b2b6d694dca85dce3b6909aed25894
54 lines
1.9 KiB
C
54 lines
1.9 KiB
C
/* This modules defines a structure representing bit strings. */
|
|
#ifndef SIMPLICITY_BITSTRING_H
|
|
#define SIMPLICITY_BITSTRING_H
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <limits.h>
|
|
#include <stdbool.h>
|
|
#include "simplicity_assert.h"
|
|
|
|
/* Represents a bitstring of length 'len' bits using an array of unsigned char.
|
|
* The bit at index 'n', where 0 <= 'n' < 'len', is located at bit '1 << (CHAR_BIT - 1 - (offset + n) % CHAR_BIT)' of
|
|
* array element 'arr[(offset + n) / CHAR_BIT]'.
|
|
* Other bits in the array may be any value.
|
|
*
|
|
* Invariant: len <= 2^31
|
|
* offset + length <= SIZE_MAX
|
|
* 0 < len implies unsigned char arr[(offset + len - 1) / CHAR_BIT + 1];
|
|
*/
|
|
typedef struct bitstring {
|
|
const unsigned char* arr;
|
|
size_t len;
|
|
size_t offset;
|
|
} bitstring;
|
|
|
|
/* Return the nth bit from a bitstring.
|
|
*
|
|
* Precondition: NULL != s
|
|
* n < s->len;
|
|
*/
|
|
static inline bool getBit(const bitstring *s, size_t n) {
|
|
size_t total_offset = s->offset + n;
|
|
simplicity_assert(n < s->len);
|
|
return 1 & (s->arr[total_offset / CHAR_BIT] >> (CHAR_BIT - 1 - (total_offset % CHAR_BIT)));
|
|
}
|
|
|
|
/* Return 8 bits from a bitstring staring from the nth bit.
|
|
*
|
|
* Precondition: NULL != s
|
|
* n + 8 <= s->len;
|
|
*/
|
|
static inline uint_fast8_t getByte(const bitstring *s, size_t n) {
|
|
simplicity_assert(8 <= s->len);
|
|
simplicity_assert(n <= s->len - 8);
|
|
size_t total_offset = s->offset + n;
|
|
if (total_offset % CHAR_BIT <= CHAR_BIT - 8) {
|
|
return (uint_fast8_t)(0xff & (s->arr[total_offset / CHAR_BIT] >> (CHAR_BIT - 8 - (total_offset % CHAR_BIT))));
|
|
} else {
|
|
/* CHAR_BIT < total_offset % CHAR_BIT + 8 */
|
|
return (uint_fast8_t)(0xff & (((1U * s->arr[total_offset / CHAR_BIT]) << (total_offset % CHAR_BIT - (CHAR_BIT - 8)))
|
|
| (s->arr[total_offset / CHAR_BIT + 1] >> (CHAR_BIT - (total_offset % CHAR_BIT - (CHAR_BIT - 8))))));
|
|
}
|
|
}
|
|
#endif
|