From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- support/dktools/dk4bf.ctr | 193 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 support/dktools/dk4bf.ctr (limited to 'support/dktools/dk4bf.ctr') diff --git a/support/dktools/dk4bf.ctr b/support/dktools/dk4bf.ctr new file mode 100644 index 0000000000..917f76185e --- /dev/null +++ b/support/dktools/dk4bf.ctr @@ -0,0 +1,193 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2015-xxxx +license = bsd + + + +%% header + +/** @file dk4bf.h Bit fields. +*/ + +#ifndef DK4ERROR_H_INCLUDED +#include "dk4error.h" +#endif + +/** Bit field structure. +*/ +typedef struct { + unsigned char *d; /**< Data buffer. */ + size_t s; /**< Number of bits in the array. */ +} dk4_bit_field_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/** Open bit field. + @param sz Size of the bit field (number of bits). + @param erp Error report, may be NULL. + @return Pointer to new bit field on success, NULL on error. + + Error codes: + - DK4_E_INVALID_ARGUMENTS
+ if sz is 0, + - DK4_E_MEMORY_ALLOCATION_FAILED
+ if not enough memory was available. +*/ +dk4_bit_field_t * +dk4bf_open(size_t sz, dk4_er_t *erp); + +/** Set one bit in a bit field. + @param dptr Bit field. + @param bitno Index of bit to modify. + @param val Bit value. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. + + Error codes: + - DK4_E_INVALID_ARGUMENTS
+ if dptr is 0 or bitno is outside the bit field size. +*/ +int +dk4bf_set(dk4_bit_field_t *dptr, size_t bitno, int val, dk4_er_t *erp); + +/** Retrieve one value from bit field. + @param dptr Address of result variable. + @param bfptr Bit field. + @param bitno Number of bit to obtain. + @param erp Error report, may be NULL. + @return 1 on success (dptr set), 0 on error (dptr unchanged). + + Error codes: + - DK4_E_INVALID_ARGUMENTS
+ if dptr or bfptr is NULL or bitno is outside the bit field size. +*/ +int +dk4bf_get(int *dptr, dk4_bit_field_t *bfptr, size_t bitno, dk4_er_t *erp); + +/** Close bit field. + @param ptr Pointer to bit field previously opened using + dk4bf_open(). +*/ +void +dk4bf_close(dk4_bit_field_t *ptr); + +#ifdef __cplusplus +} +#endif + + + +%% module + + +#include "dk4bf.h" +#include "dk4mem.h" + + + +$!trace-include + + + +/** Position of single bits within a byte. +*/ +static const unsigned char dk4bf_bits_in_byte[] = { + 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 +}; + + + +dk4_bit_field_t * +dk4bf_open(size_t sz, dk4_er_t *erp) +{ + dk4_bit_field_t *back = NULL; + size_t bsz; + if (0 < sz) { + back = dk4mem_new(dk4_bit_field_t,1,erp); + if (NULL != back) { + back->s = sz; + bsz = sz / 8; + if (0 != (sz % 8)) { + bsz++; + } + back->d = dk4mem_new(unsigned char,bsz,erp); + if (NULL == back->d) { + dk4bf_close(back); + back = NULL; + } + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; +} + + + +int +dk4bf_set(dk4_bit_field_t *dptr, size_t bitno, int val, dk4_er_t *erp) +{ + size_t bytei; /* Byte index */ + size_t biti; /* Bit index */ + int back = 0; + if (NULL != dptr) { + if (bitno < dptr->s) { + bytei = bitno / 8; + biti = bitno % 8; + if (0 != val) { + (dptr->d)[bytei] |= dk4bf_bits_in_byte[biti]; + } else { + (dptr->d)[bytei] &= (~(dk4bf_bits_in_byte[biti])); + } + back = 1; + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; +} + + + +int +dk4bf_get(int *dptr, dk4_bit_field_t *bfptr, size_t bitno, dk4_er_t *erp) +{ + size_t bytei; /* Byte index */ + size_t biti; /* Bit index within byte */ + int back = 0; + if ((NULL != dptr) && (NULL != bfptr)) { + if (bitno < bfptr->s) { + bytei = bitno / 8; + biti = bitno % 8; + if (0x00 != (((bfptr->d)[bytei]) & (dk4bf_bits_in_byte[biti]))) { + *dptr = 1; + } else { + *dptr = 0; + } + back = 1; + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; +} + + + +void +dk4bf_close(dk4_bit_field_t *ptr) +{ + if (NULL != ptr) { + dk4mem_release(ptr->d); + dk4mem_free(ptr); + } +} + -- cgit v1.2.3