jaffarCommon
Loading...
Searching...
No Matches
bitwise.hpp
Go to the documentation of this file.
1#pragma once
2
8#include "exceptions.hpp"
9#include <stddef.h>
10#include <stdint.h>
11
12namespace jaffarCommon
13{
14
15namespace bitwise
16{
17
21uint8_t bitMaskTable[8] = {0b00000001, 0b00000010, 0b00000100, 0b00001000, 0b00010000, 0b00100000, 0b01000000, 0b10000000};
22
26uint8_t bitNotMaskTable[8] = {0b11111110, 0b11111101, 0b11111011, 0b11110111, 0b11101111, 0b11011111, 0b10111111, 0b01111111};
27
40__JAFFAR_COMMON__INLINE__ void bitcopy(void* dstBufferPtr, const size_t dstBufferSize, const size_t dstBufferOffset, const void* srcBufferPtr, const size_t srcBufferSize,
41 const size_t srcBufferOffset, const size_t count, const size_t elementBitSize)
42{
43 if (elementBitSize == 0) JAFFAR_THROW_LOGIC("Element bit size must be a positive number greater than zero");
44
45 const auto dstBufferSizeBits = dstBufferSize * 8;
46 const auto srcBufferSizeBits = srcBufferSize * 8;
47 if (dstBufferOffset + elementBitSize * count > dstBufferSizeBits)
48 JAFFAR_THROW_LOGIC("The operation will overflow destination buffer (%lu + %lu * %lu > %lu)", dstBufferOffset, elementBitSize, count, dstBufferSizeBits);
49 if (srcBufferOffset + elementBitSize * count > srcBufferSizeBits)
50 JAFFAR_THROW_LOGIC("The operation will overflow source buffer (%lu + %lu * %lu > %lu)", srcBufferOffset, elementBitSize, count, srcBufferSizeBits);
51
52 uint8_t* dstBuffer = (uint8_t*)dstBufferPtr;
53 const uint8_t* srcBuffer = (const uint8_t*)srcBufferPtr;
54 const size_t totalBitCount = count * elementBitSize;
55 const size_t dstOffsetBits = dstBufferOffset * elementBitSize;
56 const size_t srcOffsetBits = srcBufferOffset * elementBitSize;
57 size_t dstPosByte = dstOffsetBits / 8;
58 uint8_t dstPosBit = dstOffsetBits % 8;
59 size_t srcPosByte = srcOffsetBits / 8;
60 uint8_t srcPosBit = srcOffsetBits % 8;
61
62 for (size_t i = 0; i < totalBitCount; i++)
63 {
64 // Clear bit in question
65 dstBuffer[dstPosByte] = dstBuffer[dstPosByte] & bitNotMaskTable[dstPosBit];
66
67 // If the corresponding bit is set in source, set it up in dst
68 if ((srcBuffer[srcPosByte] & bitMaskTable[srcPosBit]) > 0) dstBuffer[dstPosByte] = dstBuffer[dstPosByte] | bitMaskTable[dstPosBit];
69
70 // Advance bit positions
71 dstPosBit++;
72 srcPosBit++;
73
74 // If crossed a byte barrier, go over the next byte
75 if (dstPosBit == 8)
76 {
77 dstPosBit = 0;
78 dstPosByte++;
79 }
80 if (srcPosBit == 8)
81 {
82 srcPosBit = 0;
83 srcPosByte++;
84 }
85 }
86}
87
94__JAFFAR_COMMON__INLINE__ size_t getEncodingBitsForElementCount(const size_t elementCount)
95{
96 // Corner cases
97 if (elementCount == 0) return 0;
98 if (elementCount == 1) return 1;
99
100 // Calculating bit storage for the possible inputs index
101 size_t bitEncodingSize = 0;
102 size_t encodingCapacity = 1;
103 while (encodingCapacity < elementCount) { encodingCapacity <<= 1, bitEncodingSize++; };
104 return bitEncodingSize;
105}
106
113__JAFFAR_COMMON__INLINE__ size_t getByteStorageForBitCount(const size_t bitCount)
114{
115 // Calculating bit storage for the possible inputs index
116 size_t byteStorageSize = bitCount / 8;
117 if (bitCount % 8 > 0) byteStorageSize++;
118 return byteStorageSize;
119}
120
128__JAFFAR_COMMON__INLINE__ void setBitValue(void* dst, const size_t idx, const bool value)
129{
130 size_t dstPosByte = idx / 8;
131 uint8_t dstPosBit = idx % 8;
132 auto dstPtr = (uint8_t*)dst;
133
134 if (value == false) dstPtr[dstPosByte] = dstPtr[dstPosByte] & bitNotMaskTable[dstPosBit];
135 if (value == true) dstPtr[dstPosByte] = dstPtr[dstPosByte] | bitMaskTable[dstPosBit];
136}
137
145__JAFFAR_COMMON__INLINE__ bool getBitValue(const void* src, const size_t idx)
146{
147 size_t srcPosByte = idx / 8;
148 uint8_t srcPosBit = idx % 8;
149 auto srcPtr = (const uint8_t*)src;
150
151 return (srcPtr[srcPosByte] & bitMaskTable[srcPosBit]) > 0;
152}
153
161__JAFFAR_COMMON__INLINE__ bool getBitFlag(const uint8_t value, const uint8_t idx)
162{
163 if (idx > 7) JAFFAR_THROW_LOGIC("Provided bit index higher than 7 for a an 8-bit value");
164
165 if (((idx == 7) && (value & 0b10000000)) || ((idx == 6) && (value & 0b01000000)) || ((idx == 5) && (value & 0b00100000)) || ((idx == 4) && (value & 0b00010000)) ||
166 ((idx == 3) && (value & 0b00001000)) || ((idx == 2) && (value & 0b00000100)) || ((idx == 1) && (value & 0b00000010)) || ((idx == 0) && (value & 0b00000001)))
167 return true;
168 return false;
169}
170
171} // namespace bitwise
172
173} // namespace jaffarCommon
__JAFFAR_COMMON__INLINE__ size_t getByteStorageForBitCount(const size_t bitCount)
Definition bitwise.hpp:113
__JAFFAR_COMMON__INLINE__ void bitcopy(void *dstBufferPtr, const size_t dstBufferSize, const size_t dstBufferOffset, const void *srcBufferPtr, const size_t srcBufferSize, const size_t srcBufferOffset, const size_t count, const size_t elementBitSize)
Definition bitwise.hpp:40
__JAFFAR_COMMON__INLINE__ void setBitValue(void *dst, const size_t idx, const bool value)
Definition bitwise.hpp:128
__JAFFAR_COMMON__INLINE__ bool getBitValue(const void *src, const size_t idx)
Definition bitwise.hpp:145
__JAFFAR_COMMON__INLINE__ size_t getEncodingBitsForElementCount(const size_t elementCount)
Definition bitwise.hpp:94
__JAFFAR_COMMON__INLINE__ bool getBitFlag(const uint8_t value, const uint8_t idx)
Definition bitwise.hpp:161
uint8_t bitNotMaskTable[8]
Definition bitwise.hpp:26
uint8_t bitMaskTable[8]
Definition bitwise.hpp:21
Contains common functions for exception throwing.
#define JAFFAR_THROW_LOGIC(...)
Definition exceptions.hpp:27