GY-63_MS5611/libraries/BitArray/BitArray.cpp

241 lines
5.1 KiB
C++
Raw Normal View History

2015-11-22 13:16:39 -05:00
//
// FILE: BitArray.cpp
// AUTHOR: Rob Tillaart
2021-12-14 05:17:14 -05:00
// VERSION: 0.2.4
2015-11-22 13:16:39 -05:00
// PURPOSE: BitArray library for Arduino
2020-11-27 05:10:47 -05:00
// URL: https://github.com/RobTillaart/BitArray
// http://forum.arduino.cc/index.php?topic=361167
2015-11-22 13:16:39 -05:00
//
2021-10-19 10:11:27 -04:00
// HISTORY
// 0.1.00 initial version
// 0.1.01 added clear() + fixed set bug
// 0.1.02 first stable version (at last)
// 0.1.03 refactoring
// 0.1.04 improve performance
// 0.1.05 added upper limits
// 0.1.06 refactored
// 0.1.07 private calls inline -> performance & footprint
// 0.1.8 added toggle
// 0.1.9 fix constructor bug
// 0.2.0 2020-03-28 #pragma once, readme, fix Fibonacci demo
// 0.2.1 2020-06-05 fix library.json
// 0.2.2 2020-12-14 add Arduino-CI + unit test
// 0.2.3 2021-10-19 update Arduino-CI + setAll(value)
2021-12-14 05:17:14 -05:00
// 0.2.4 2021-12-14 update library.json, license, minor edits
2020-11-27 05:10:47 -05:00
2021-01-29 06:31:58 -05:00
2015-11-22 13:16:39 -05:00
#include "BitArray.h"
2021-10-19 10:11:27 -04:00
2020-11-27 05:10:47 -05:00
BitArray::BitArray()
{
for (uint8_t i = 0; i < BA_MAX_SEGMENTS; i++)
{
_ar[i] = NULL;
}
}
2021-10-19 10:11:27 -04:00
2015-11-22 13:16:39 -05:00
BitArray::~BitArray()
{
2015-12-09 15:59:28 -05:00
for (uint8_t i = 0; i < BA_MAX_SEGMENTS; i++)
2015-11-22 13:16:39 -05:00
{
if (_ar[i]) free(_ar[i]);
}
}
2021-10-19 10:11:27 -04:00
2015-12-09 15:59:28 -05:00
uint8_t BitArray::begin(const uint8_t bits, const uint16_t size)
2015-11-22 13:16:39 -05:00
{
2015-12-09 15:59:28 -05:00
if (bits == 0 || bits > 32)
2015-11-22 13:16:39 -05:00
{
2015-12-09 15:59:28 -05:00
_error = BA_ELEMENT_SIZE_ERR;
return _error;
2015-11-22 13:16:39 -05:00
}
2015-12-09 15:59:28 -05:00
if ((1UL * bits * size)/8 > (1UL * BA_MAX_SEGMENTS * BA_SEGMENT_SIZE))
2015-11-22 13:16:39 -05:00
{
2015-12-09 15:59:28 -05:00
_error = BA_SIZE_ERR;
2015-11-22 13:16:39 -05:00
return _error;
}
2015-12-09 15:59:28 -05:00
for (uint8_t i = 0; i < BA_MAX_SEGMENTS; i++)
{
if (_ar[i]) free(_ar[i]);
}
2015-11-22 13:16:39 -05:00
_segments = 0;
2015-12-09 15:59:28 -05:00
_bits = bits;
_bytes = (_bits * size + 7) / 8;
uint16_t b = _bytes;
2015-11-22 13:16:39 -05:00
while (b > 0)
{
2021-10-19 10:11:27 -04:00
_ar[_segments] = (uint8_t*) malloc(min(b, (uint16_t) BA_SEGMENT_SIZE));
if (_ar[_segments] == NULL)
2015-11-22 13:16:39 -05:00
{
2015-12-09 15:59:28 -05:00
_error = BA_NO_MEMORY_ERR;
2015-11-22 13:16:39 -05:00
return _error;
}
2021-10-19 10:11:27 -04:00
b = b - min(b, (uint16_t) BA_SEGMENT_SIZE);
2015-11-22 13:16:39 -05:00
_segments++;
}
_error = BA_OK;
return _error;
}
2021-10-19 10:11:27 -04:00
2021-12-14 05:17:14 -05:00
uint32_t BitArray::get(const uint16_t index)
2015-11-22 13:16:39 -05:00
{
// if (_error != BA_OK) return BA_ERR;
2021-12-14 05:17:14 -05:00
// if (index >= _size) return BA_IDX_RANGE;
2015-11-22 13:16:39 -05:00
uint32_t v = 0;
2021-12-14 05:17:14 -05:00
uint16_t pos = index * _bits;
2020-11-27 05:10:47 -05:00
2015-12-09 15:59:28 -05:00
for (uint8_t i = _bits; i-- > 0;)
2015-11-22 13:16:39 -05:00
{
v <<= 1;
v += _bitget(pos + i);
}
return v;
}
2020-11-27 05:10:47 -05:00
2021-12-14 05:17:14 -05:00
uint32_t BitArray::set(const uint16_t index, uint32_t value)
2015-11-22 13:16:39 -05:00
{
// if (_error != BA_OK) return BA_ERR;
2021-12-14 05:17:14 -05:00
// if (index >= _size) return BA_IDX_RANGE;
uint16_t pos = index * _bits;
2015-11-22 13:16:39 -05:00
uint32_t mask = 1UL;
2015-12-09 15:59:28 -05:00
for (uint8_t i = 0; i < _bits; i++)
2015-11-22 13:16:39 -05:00
{
2015-12-09 15:59:28 -05:00
uint8_t v = (value & mask) > 0 ? 1 : 0;
2015-11-22 13:16:39 -05:00
_bitset(pos + i, v);
mask <<= 1;
}
return value;
}
2021-10-19 10:11:27 -04:00
2021-12-14 05:17:14 -05:00
uint32_t BitArray::toggle(const uint16_t index)
2017-07-16 07:39:43 -04:00
{
// if (_error != BA_OK) return BA_ERR;
2021-12-14 05:17:14 -05:00
// if (index >= _size) return BA_IDX_RANGE;
2017-07-16 07:39:43 -04:00
uint32_t v = 0;
2021-12-14 05:17:14 -05:00
uint16_t pos = index * _bits;
2017-07-16 07:39:43 -04:00
for (uint8_t i = _bits; i-- > 0;)
{
v <<= 1;
v += _bittoggle(pos + i);
}
return v;
}
2021-10-19 10:11:27 -04:00
2015-11-22 13:16:39 -05:00
void BitArray::clear()
{
uint16_t b = _bytes;
2015-12-09 15:59:28 -05:00
for (uint8_t s = 0; s < _segments; s++)
2015-11-22 13:16:39 -05:00
{
2021-01-29 06:31:58 -05:00
uint8_t *p = _ar[s];
2015-11-22 13:16:39 -05:00
if (p)
{
2021-10-19 10:11:27 -04:00
uint8_t t = min(b, (uint16_t) BA_SEGMENT_SIZE);
2021-01-29 06:31:58 -05:00
b -= t;
while(t--)
{
2021-01-29 06:31:58 -05:00
*p++ = 0;
2015-11-22 13:16:39 -05:00
}
}
if (b == 0) break;
2015-11-22 13:16:39 -05:00
}
}
2015-11-22 13:16:39 -05:00
2021-10-19 10:11:27 -04:00
void BitArray::setAll(uint32_t value)
{
for (uint16_t i = 0; i < capacity(); i++)
{
set(i, value);
}
}
// 16 bit address usage is faster
// TODO verify correctness
//
2021-01-29 06:31:58 -05:00
// void BitArray::clear()
// {
// uint16_t b = _bytes;
// for (uint8_t s = 0; s < _segments; s++)
// {
// uint8_t *q = _ar[s];
// uint16_t *p = (uint16_t*)q;
// if (p)
// {
// for (uint8_t t = 0; t < BA_SEGMENT_SIZE/2; t++)
// {
// *p++ = 0; // might be bug @ edge..
// }
// }
// if (b == 0) break;
// }
// }
2021-10-19 10:11:27 -04:00
2015-11-22 13:16:39 -05:00
// PRIVATE
inline uint8_t BitArray::_bitget(uint16_t pos)
2015-11-22 13:16:39 -05:00
{
uint8_t se = 0;
uint16_t re = pos;
2015-12-09 15:59:28 -05:00
while (re >= (BA_SEGMENT_SIZE * 8)) // 8 == #bits in uint8_t
{
se++;
re -= (BA_SEGMENT_SIZE * 8);
}
uint8_t by = re / 8;
uint8_t bi = re & 7;
2015-12-09 15:59:28 -05:00
uint8_t * p = _ar[se];
2020-11-27 05:10:47 -05:00
return (p[by] >> bi) & 0x01; // bitRead(p[by], bi);
2015-11-22 13:16:39 -05:00
}
2021-10-19 10:11:27 -04:00
inline void BitArray::_bitset(uint16_t pos, uint8_t value)
2015-11-22 13:16:39 -05:00
{
uint8_t se = 0;
uint16_t re = pos;
2017-07-16 07:39:43 -04:00
while (re >= (BA_SEGMENT_SIZE * 8)) // 8 == #bits in uint8_t
{
se++;
re -= (BA_SEGMENT_SIZE * 8);
}
uint8_t by = re / 8;
uint8_t bi = re & 7;
2015-12-09 15:59:28 -05:00
uint8_t * p = _ar[se];
2020-11-27 05:10:47 -05:00
if (value == 0) p[by] &= ~(1 << bi); // bitClear(p[by], bi);
else p[by] |= (1 << bi); // bitSet(p[by], bi);
2015-11-22 13:16:39 -05:00
}
2021-10-19 10:11:27 -04:00
2017-07-16 07:39:43 -04:00
inline uint8_t BitArray::_bittoggle(const uint16_t pos)
{
uint8_t se = 0;
uint16_t re = pos;
while (re >= (BA_SEGMENT_SIZE * 8)) // 8 == #bits in uint8_t
{
se++;
re -= (BA_SEGMENT_SIZE * 8);
}
uint8_t by = re / 8;
uint8_t bi = re & 7;
uint8_t * p = _ar[se];
2020-11-27 05:10:47 -05:00
2017-07-16 07:39:43 -04:00
uint8_t mask = 1 << bi;
p[by] ^= mask;
return (mask > 0);
}
2021-10-19 10:11:27 -04:00
// -- END OF FILE --