Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 1 | /** @file hei_bit_string.cpp |
| 2 | * @brief BitString and BitStringBuffer class definitions |
| 3 | */ |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 4 | |
Zane Shelley | 995be6c | 2021-02-24 15:48:55 -0600 | [diff] [blame] | 5 | #include <util/hei_bit_string.hpp> |
Zane Shelley | d507351 | 2021-01-14 12:51:18 -0600 | [diff] [blame] | 6 | #include <util/hei_includes.hpp> |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 7 | |
| 8 | #include <algorithm> |
| 9 | |
Zane Shelley | 871adec | 2019-07-30 11:01:39 -0500 | [diff] [blame] | 10 | namespace libhei |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 11 | { |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 12 | |
Zane Shelley | 72fd2e4 | 2022-11-12 12:14:53 -0600 | [diff] [blame] | 13 | // ############################################################################## |
| 14 | // BitString class |
| 15 | // ############################################################################## |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 16 | |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 17 | // number of bits in a uint64_t |
Ben Tyner | 7c79605 | 2020-02-03 19:00:37 -0600 | [diff] [blame] | 18 | const uint64_t BitString::UINT64_BIT_LEN = sizeof(uint64_t) * 8; |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 19 | // number of bits in a uint8_t |
Ben Tyner | 7c79605 | 2020-02-03 19:00:37 -0600 | [diff] [blame] | 20 | const uint64_t BitString::UINT8_BIT_LEN = sizeof(uint8_t) * 8; |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 21 | |
| 22 | //------------------------------------------------------------------------------ |
| 23 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 24 | uint64_t BitString::getFieldRight(uint64_t i_pos, uint64_t i_len) const |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 25 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 26 | HEI_ASSERT(nullptr != getBufAddr()); // must to have a valid address |
| 27 | HEI_ASSERT(0 < i_len); // must have at least one bit |
| 28 | HEI_ASSERT(i_len <= UINT64_BIT_LEN); // i_len length must be valid |
| 29 | HEI_ASSERT(i_pos + i_len <= getBitLen()); // field must be within range |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 30 | |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 31 | // Get the relative address of this byte and the relative starting position |
| 32 | // within the byte. |
Patrick Williams | 2f7537d | 2023-05-10 07:51:39 -0500 | [diff] [blame] | 33 | uint64_t relPos = 0; |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame] | 34 | uint8_t* relAddr = getRelativePosition(relPos, i_pos); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 35 | |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 36 | // Get the length of the target bit field within this byte and the length of |
| 37 | // the bit field for any remaining bits. |
Patrick Williams | 2f7537d | 2023-05-10 07:51:39 -0500 | [diff] [blame] | 38 | uint64_t bf_len = i_len; |
Zane Shelley | d0af358 | 2019-09-19 10:48:59 -0500 | [diff] [blame] | 39 | uint64_t remain_len = 0; |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 40 | if (UINT8_BIT_LEN < relPos + i_len) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 41 | { |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 42 | // The target bit field crosses a byte boundary. So truncate the bit |
| 43 | // length for this byte and update the remaining length. |
Patrick Williams | 2f7537d | 2023-05-10 07:51:39 -0500 | [diff] [blame] | 44 | bf_len = UINT8_BIT_LEN - relPos; |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 45 | remain_len = i_len - bf_len; |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 46 | } |
| 47 | |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 48 | // Get the target bit field within this byte (right justified). |
| 49 | uint8_t bf = *relAddr; |
| 50 | bf <<= relPos; // Mask off uneeded bits on the left side. |
| 51 | bf >>= UINT8_BIT_LEN - bf_len; // Right justify the value. |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 52 | |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 53 | // Check for any remaining bits after this target byte. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 54 | if (0 != remain_len) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 55 | { |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 56 | // Recursively call this function on the remaining bits and push them |
| 57 | // into the right side of the return value. |
| 58 | uint64_t val = static_cast<uint64_t>(bf) << remain_len; |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 59 | return val | getFieldRight(i_pos + bf_len, remain_len); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 60 | } |
| 61 | |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 62 | // Nothing more to do. Simply return this bit field. |
| 63 | return bf; |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 64 | } |
| 65 | |
| 66 | //------------------------------------------------------------------------------ |
| 67 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 68 | void BitString::setFieldLeft(uint64_t i_pos, uint64_t i_len, uint64_t i_val) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 69 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 70 | HEI_ASSERT(nullptr != getBufAddr()); // must to have a valid address |
| 71 | HEI_ASSERT(0 < i_len); // must have at least one bit |
| 72 | HEI_ASSERT(i_len <= UINT64_BIT_LEN); // i_len length must be valid |
| 73 | HEI_ASSERT(i_pos + i_len <= getBitLen()); // field must be within range |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 74 | |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 75 | // Get the relative address of this byte and the relative starting position |
| 76 | // within the byte. |
Patrick Williams | 2f7537d | 2023-05-10 07:51:39 -0500 | [diff] [blame] | 77 | uint64_t relPos = 0; |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame] | 78 | uint8_t* relAddr = getRelativePosition(relPos, i_pos); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 79 | |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 80 | // Get the length of the target bit field within this byte and the length of |
| 81 | // the bit field for any remaining bits. |
Patrick Williams | 2f7537d | 2023-05-10 07:51:39 -0500 | [diff] [blame] | 82 | uint64_t bf_len = i_len; |
Zane Shelley | d0af358 | 2019-09-19 10:48:59 -0500 | [diff] [blame] | 83 | uint64_t remain_len = 0; |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 84 | if (UINT8_BIT_LEN < relPos + i_len) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 85 | { |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 86 | // The target bit field crosses a byte boundary. So truncate the bit |
| 87 | // length for this byte and update the remaining length. |
Patrick Williams | 2f7537d | 2023-05-10 07:51:39 -0500 | [diff] [blame] | 88 | bf_len = UINT8_BIT_LEN - relPos; |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 89 | remain_len = i_len - bf_len; |
| 90 | } |
| 91 | |
| 92 | // It is possible there are bits in this byte on either side of the target |
| 93 | // bit field that must be preserved. Get the length of each of those bit |
| 94 | // fields. |
Zane Shelley | d0af358 | 2019-09-19 10:48:59 -0500 | [diff] [blame] | 95 | uint64_t bf_l_len = relPos; |
| 96 | uint64_t bf_r_len = UINT8_BIT_LEN - (bf_l_len + bf_len); |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 97 | |
| 98 | // Get the target bit field from the left justified inputed value. |
| 99 | uint8_t bf = (i_val >> (UINT64_BIT_LEN - bf_len)) << bf_r_len; |
| 100 | |
| 101 | // Get the bit fields on either side of the target bit field. |
Zane Shelley | d0af358 | 2019-09-19 10:48:59 -0500 | [diff] [blame] | 102 | uint64_t bf_l_shift = UINT8_BIT_LEN - bf_l_len; |
| 103 | uint64_t bf_r_shift = UINT8_BIT_LEN - bf_r_len; |
Zane Shelley | 7c8faa1 | 2019-10-28 22:26:28 -0500 | [diff] [blame] | 104 | |
Zane Shelley | 7f7a42d | 2019-10-28 13:28:31 -0500 | [diff] [blame] | 105 | uint8_t bf_l = *relAddr; |
| 106 | bf_l >>= bf_l_shift; |
| 107 | bf_l <<= bf_l_shift; |
Zane Shelley | 7c8faa1 | 2019-10-28 22:26:28 -0500 | [diff] [blame] | 108 | |
Zane Shelley | 7f7a42d | 2019-10-28 13:28:31 -0500 | [diff] [blame] | 109 | uint8_t bf_r = *relAddr; |
| 110 | bf_r <<= bf_r_shift; |
| 111 | bf_r >>= bf_r_shift; |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 112 | |
| 113 | // Combine all three parts of the byte and write it out to memory. |
| 114 | *relAddr = bf_l | bf | bf_r; |
| 115 | |
| 116 | // Check for any remaining bits after this target byte. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 117 | if (0 != remain_len) |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 118 | { |
| 119 | // Recursively call this function on the remaining bits. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 120 | setFieldLeft(i_pos + bf_len, remain_len, i_val << bf_len); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 121 | } |
| 122 | } |
| 123 | |
| 124 | //------------------------------------------------------------------------------ |
| 125 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 126 | void BitString::setPattern(uint64_t i_sPos, uint64_t i_sLen, uint64_t i_pattern, |
| 127 | uint64_t i_pLen) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 128 | { |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 129 | HEI_ASSERT(nullptr != getBufAddr()); // must to have a valid address |
| 130 | HEI_ASSERT(0 < i_sLen); // must have at least one bit |
| 131 | HEI_ASSERT(i_sPos + i_sLen <= getBitLen()); // field must be within range |
| 132 | HEI_ASSERT(0 < i_pLen); // must have at least one bit |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 133 | HEI_ASSERT(i_pLen <= UINT64_BIT_LEN); // i_pLen length must be valid |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 134 | |
| 135 | // Get a bit string for the pattern subset (right justified). |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 136 | // Note that we cannot use a BitStringBuffer here because this function |
| 137 | // could be used in the constructor of BitStringBuffer, which could causes |
| 138 | // an infinite loop. |
| 139 | uint8_t a[sizeof(i_pattern)] = {}; |
Zane Shelley | c477199 | 2019-10-28 22:01:49 -0500 | [diff] [blame] | 140 | BitString bs{sizeof(i_pattern) * 8, a}; |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 141 | bs.setFieldRight(0, i_pLen, i_pattern); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 142 | |
| 143 | // Iterate the range in chunks the size of i_pLen. |
Zane Shelley | d0af358 | 2019-09-19 10:48:59 -0500 | [diff] [blame] | 144 | uint64_t endPos = i_sPos + i_sLen; |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 145 | for (uint64_t pos = i_sPos; pos < endPos; pos += i_pLen) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 146 | { |
| 147 | // The true chunk size is either i_pLen or the leftovers at the end. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 148 | uint64_t len = std::min(i_pLen, endPos - pos); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 149 | |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 150 | // Get this chunk's pattern value, truncate (right justified) if needed. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 151 | uint64_t pattern = bs.getFieldRight(0, len); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 152 | |
| 153 | // Set the pattern in this string. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 154 | setFieldRight(pos, len, pattern); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 155 | } |
| 156 | } |
| 157 | |
| 158 | //------------------------------------------------------------------------------ |
| 159 | |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame] | 160 | void BitString::setString(const BitString& i_sStr, uint64_t i_sPos, |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 161 | uint64_t i_sLen, uint64_t i_dPos) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 162 | { |
| 163 | // Ensure the source parameters are valid. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 164 | HEI_ASSERT(nullptr != i_sStr.getBufAddr()); |
| 165 | HEI_ASSERT(0 < i_sLen); // at least one bit to copy |
| 166 | HEI_ASSERT(i_sPos + i_sLen <= i_sStr.getBitLen()); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 167 | |
| 168 | // Ensure the destination has at least one bit available to copy. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 169 | HEI_ASSERT(nullptr != getBufAddr()); |
| 170 | HEI_ASSERT(i_dPos < getBitLen()); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 171 | |
| 172 | // If the source length is greater than the destination length than the |
| 173 | // extra source bits are ignored. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 174 | uint64_t actLen = std::min(i_sLen, getBitLen() - i_dPos); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 175 | |
| 176 | // The bit strings may be in overlapping memory spaces. So we need to copy |
| 177 | // the data in the correct direction to prevent overlapping. |
Zane Shelley | d0af358 | 2019-09-19 10:48:59 -0500 | [diff] [blame] | 178 | uint64_t sRelOffset = 0, dRelOffset = 0; |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame] | 179 | uint8_t* sRelAddr = i_sStr.getRelativePosition(sRelOffset, i_sPos); |
Zane Shelley | 7c8faa1 | 2019-10-28 22:26:28 -0500 | [diff] [blame] | 180 | uint8_t* dRelAddr = getRelativePosition(dRelOffset, i_dPos); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 181 | |
| 182 | // Copy the data. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 183 | if ((dRelAddr == sRelAddr) && (dRelOffset == sRelOffset)) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 184 | { |
| 185 | // Do nothing. The source and destination are the same. |
| 186 | } |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 187 | else if ((dRelAddr < sRelAddr) || |
| 188 | ((dRelAddr == sRelAddr) && (dRelOffset < sRelOffset))) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 189 | { |
| 190 | // Copy the data forward. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 191 | for (uint64_t pos = 0; pos < actLen; pos += UINT64_BIT_LEN) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 192 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 193 | uint64_t len = std::min(actLen - pos, UINT64_BIT_LEN); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 194 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 195 | uint64_t value = i_sStr.getFieldRight(i_sPos + pos, len); |
| 196 | setFieldRight(i_dPos + pos, len, value); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 197 | } |
| 198 | } |
| 199 | else // Copy the data backwards. |
| 200 | { |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 201 | // Get the first position of the last chunk (byte aligned). |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 202 | uint64_t lastPos = ((actLen - 1) / UINT64_BIT_LEN) * UINT64_BIT_LEN; |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 203 | |
| 204 | // Start with the last chunk and work backwards. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 205 | for (int32_t pos = lastPos; 0 <= pos; pos -= UINT64_BIT_LEN) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 206 | { |
Patrick Williams | 2f7537d | 2023-05-10 07:51:39 -0500 | [diff] [blame] | 207 | uint64_t len = std::min(actLen - pos, UINT64_BIT_LEN); |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 208 | uint64_t value = i_sStr.getFieldRight(i_sPos + pos, len); |
| 209 | setFieldRight(i_dPos + pos, len, value); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 210 | } |
| 211 | } |
| 212 | } |
| 213 | |
| 214 | //------------------------------------------------------------------------------ |
| 215 | |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame] | 216 | void BitString::maskString(const BitString& i_mask) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 217 | { |
| 218 | // Get the length of the smallest string. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 219 | uint64_t actLen = std::min(getBitLen(), i_mask.getBitLen()); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 220 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 221 | for (uint64_t pos = 0; pos < actLen; pos += UINT64_BIT_LEN) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 222 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 223 | uint64_t len = std::min(actLen - pos, UINT64_BIT_LEN); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 224 | |
Zane Shelley | 7c8faa1 | 2019-10-28 22:26:28 -0500 | [diff] [blame] | 225 | uint64_t dVal = getFieldRight(pos, len); |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 226 | uint64_t sVal = i_mask.getFieldRight(pos, len); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 227 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 228 | setFieldRight(pos, len, dVal & ~sVal); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 229 | } |
| 230 | } |
| 231 | |
| 232 | //------------------------------------------------------------------------------ |
| 233 | |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame] | 234 | bool BitString::isEqual(const BitString& i_str) const |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 235 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 236 | if (getBitLen() != i_str.getBitLen()) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 237 | return false; // size not equal |
| 238 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 239 | for (uint64_t pos = 0; pos < getBitLen(); pos += UINT64_BIT_LEN) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 240 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 241 | uint64_t len = std::min(getBitLen() - pos, UINT64_BIT_LEN); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 242 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 243 | if (getFieldRight(pos, len) != i_str.getFieldRight(pos, len)) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 244 | return false; // bit strings do not match |
| 245 | } |
| 246 | |
| 247 | return true; // bit strings match |
| 248 | } |
| 249 | |
| 250 | //------------------------------------------------------------------------------ |
| 251 | |
| 252 | bool BitString::isZero() const |
| 253 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 254 | for (uint64_t pos = 0; pos < getBitLen(); pos += UINT64_BIT_LEN) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 255 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 256 | uint64_t len = std::min(getBitLen() - pos, UINT64_BIT_LEN); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 257 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 258 | if (0 != getFieldRight(pos, len)) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 259 | return false; // something is non-zero |
| 260 | } |
| 261 | |
| 262 | return true; // everything was zero |
| 263 | } |
| 264 | |
| 265 | //------------------------------------------------------------------------------ |
| 266 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 267 | uint64_t BitString::getSetCount(uint64_t i_pos, uint64_t i_len) const |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 268 | { |
Zane Shelley | d0af358 | 2019-09-19 10:48:59 -0500 | [diff] [blame] | 269 | uint64_t endPos = i_pos + i_len; |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 270 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 271 | HEI_ASSERT(endPos <= getBitLen()); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 272 | |
Zane Shelley | d0af358 | 2019-09-19 10:48:59 -0500 | [diff] [blame] | 273 | uint64_t count = 0; |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 274 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 275 | for (uint64_t i = i_pos; i < endPos; i++) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 276 | { |
Zane Shelley | 7f7a42d | 2019-10-28 13:28:31 -0500 | [diff] [blame] | 277 | if (isBitSet(i)) |
| 278 | count++; |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 279 | } |
| 280 | |
| 281 | return count; |
| 282 | } |
| 283 | |
| 284 | //------------------------------------------------------------------------------ |
| 285 | |
Zane Shelley | ec06f82 | 2019-12-05 22:23:19 -0600 | [diff] [blame] | 286 | bool BitString::operator<(const BitString& i_str) const |
| 287 | { |
Zane Shelley | 6eb6190 | 2020-05-15 22:25:58 -0500 | [diff] [blame] | 288 | if (getBitLen() < i_str.getBitLen()) |
Zane Shelley | ec06f82 | 2019-12-05 22:23:19 -0600 | [diff] [blame] | 289 | { |
Zane Shelley | 6eb6190 | 2020-05-15 22:25:58 -0500 | [diff] [blame] | 290 | return true; |
| 291 | } |
| 292 | else if (getBitLen() == i_str.getBitLen()) |
| 293 | { |
| 294 | // Can only compare the bit strings if the length is the same. |
| 295 | for (uint64_t pos = 0; pos < getBitLen(); pos += UINT64_BIT_LEN) |
Zane Shelley | ec06f82 | 2019-12-05 22:23:19 -0600 | [diff] [blame] | 296 | { |
Zane Shelley | 6eb6190 | 2020-05-15 22:25:58 -0500 | [diff] [blame] | 297 | uint64_t len = std::min(getBitLen() - pos, UINT64_BIT_LEN); |
| 298 | |
| 299 | auto l_str = getFieldRight(pos, len); |
| 300 | auto r_str = i_str.getFieldRight(pos, len); |
| 301 | |
| 302 | if (l_str < r_str) |
| 303 | { |
| 304 | return true; |
| 305 | } |
| 306 | // The loop can only continue if the values are equal. |
| 307 | else if (l_str > r_str) |
| 308 | { |
| 309 | return false; |
| 310 | } |
Zane Shelley | ec06f82 | 2019-12-05 22:23:19 -0600 | [diff] [blame] | 311 | } |
| 312 | } |
| 313 | |
| 314 | return false; |
| 315 | } |
| 316 | |
| 317 | //------------------------------------------------------------------------------ |
| 318 | |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 319 | BitStringBuffer BitString::operator~() const |
| 320 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 321 | BitStringBuffer bsb(getBitLen()); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 322 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 323 | for (uint64_t pos = 0; pos < getBitLen(); pos += UINT64_BIT_LEN) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 324 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 325 | uint64_t len = std::min(getBitLen() - pos, UINT64_BIT_LEN); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 326 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 327 | uint64_t dVal = getFieldRight(pos, len); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 328 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 329 | bsb.setFieldRight(pos, len, ~dVal); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 330 | } |
| 331 | |
| 332 | return bsb; |
| 333 | } |
| 334 | |
| 335 | //------------------------------------------------------------------------------ |
| 336 | |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame] | 337 | BitStringBuffer BitString::operator&(const BitString& i_bs) const |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 338 | { |
| 339 | // Get the length of the smallest string. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 340 | uint64_t actLen = std::min(getBitLen(), i_bs.getBitLen()); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 341 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 342 | BitStringBuffer bsb(actLen); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 343 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 344 | for (uint64_t pos = 0; pos < actLen; pos += UINT64_BIT_LEN) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 345 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 346 | uint64_t len = std::min(actLen - pos, UINT64_BIT_LEN); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 347 | |
Zane Shelley | 7c8faa1 | 2019-10-28 22:26:28 -0500 | [diff] [blame] | 348 | uint64_t dVal = getFieldRight(pos, len); |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 349 | uint64_t sVal = i_bs.getFieldRight(pos, len); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 350 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 351 | bsb.setFieldRight(pos, len, dVal & sVal); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 352 | } |
| 353 | |
| 354 | return bsb; |
| 355 | } |
| 356 | |
| 357 | //------------------------------------------------------------------------------ |
| 358 | |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame] | 359 | BitStringBuffer BitString::operator|(const BitString& i_bs) const |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 360 | { |
| 361 | // Get the length of the smallest string. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 362 | uint64_t actLen = std::min(getBitLen(), i_bs.getBitLen()); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 363 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 364 | BitStringBuffer bsb(actLen); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 365 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 366 | for (uint64_t pos = 0; pos < actLen; pos += UINT64_BIT_LEN) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 367 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 368 | uint64_t len = std::min(actLen - pos, UINT64_BIT_LEN); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 369 | |
Zane Shelley | 7c8faa1 | 2019-10-28 22:26:28 -0500 | [diff] [blame] | 370 | uint64_t dVal = getFieldRight(pos, len); |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 371 | uint64_t sVal = i_bs.getFieldRight(pos, len); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 372 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 373 | bsb.setFieldRight(pos, len, dVal | sVal); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 374 | } |
| 375 | |
| 376 | return bsb; |
| 377 | } |
| 378 | |
| 379 | //------------------------------------------------------------------------------ |
| 380 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 381 | BitStringBuffer BitString::operator>>(uint64_t i_shift) const |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 382 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 383 | BitStringBuffer bsb(getBitLen()); // default all zeros |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 384 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 385 | if (i_shift < getBitLen()) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 386 | { |
| 387 | // bso overlays bsb, containing the shifted offset. |
Zane Shelley | c477199 | 2019-10-28 22:01:49 -0500 | [diff] [blame] | 388 | BitString bso(bsb.getBitLen() - i_shift, bsb.getBufAddr(), i_shift); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 389 | |
| 390 | // Copy this into bso. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 391 | bso.setString(*this); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 392 | } |
| 393 | |
| 394 | return bsb; |
| 395 | } |
| 396 | |
| 397 | //------------------------------------------------------------------------------ |
| 398 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 399 | BitStringBuffer BitString::operator<<(uint64_t i_shift) const |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 400 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 401 | BitStringBuffer bsb(getBitLen()); // default all zeros |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 402 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 403 | if (i_shift < getBitLen()) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 404 | { |
| 405 | // bso overlays *this, containing the shifted offset. |
Zane Shelley | c477199 | 2019-10-28 22:01:49 -0500 | [diff] [blame] | 406 | BitString bso(this->getBitLen() - i_shift, this->getBufAddr(), i_shift); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 407 | |
| 408 | // Copy bso into bsb. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 409 | bsb.setString(bso); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 410 | } |
| 411 | |
| 412 | return bsb; |
| 413 | } |
| 414 | |
| 415 | //------------------------------------------------------------------------------ |
| 416 | |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame] | 417 | uint8_t* BitString::getRelativePosition(uint64_t& o_relPos, |
Zane Shelley | 7c8faa1 | 2019-10-28 22:26:28 -0500 | [diff] [blame] | 418 | uint64_t i_absPos) const |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 419 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 420 | HEI_ASSERT(nullptr != getBufAddr()); // must to have a valid address |
| 421 | HEI_ASSERT(i_absPos < getBitLen()); // must be a valid position |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 422 | |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 423 | o_relPos = (i_absPos + iv_offset) % UINT8_BIT_LEN; |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 424 | |
Zane Shelley | 5a78fa8 | 2022-09-16 16:49:58 -0500 | [diff] [blame] | 425 | return (iv_bufAddr + ((i_absPos + iv_offset) / UINT8_BIT_LEN)); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 426 | } |
| 427 | |
Zane Shelley | 72fd2e4 | 2022-11-12 12:14:53 -0600 | [diff] [blame] | 428 | // ############################################################################## |
| 429 | // BitStringBuffer class |
| 430 | // ############################################################################## |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 431 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 432 | BitStringBuffer::BitStringBuffer(uint64_t i_bitLen) : |
| 433 | BitString(i_bitLen, nullptr) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 434 | { |
| 435 | initBuffer(); |
| 436 | } |
| 437 | |
| 438 | //------------------------------------------------------------------------------ |
| 439 | |
| 440 | BitStringBuffer::~BitStringBuffer() |
| 441 | { |
Zane Shelley | 5a78fa8 | 2022-09-16 16:49:58 -0500 | [diff] [blame] | 442 | delete[] getBufAddr(); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 443 | } |
| 444 | |
| 445 | //------------------------------------------------------------------------------ |
| 446 | |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame] | 447 | BitStringBuffer::BitStringBuffer(const BitString& i_bs) : |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 448 | BitString(i_bs.getBitLen(), nullptr) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 449 | { |
| 450 | initBuffer(); |
Zane Shelley | 7f7a42d | 2019-10-28 13:28:31 -0500 | [diff] [blame] | 451 | if (!i_bs.isZero()) |
| 452 | { |
| 453 | setString(i_bs); |
| 454 | } |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 455 | } |
| 456 | |
| 457 | //------------------------------------------------------------------------------ |
| 458 | |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame] | 459 | BitStringBuffer::BitStringBuffer(const BitStringBuffer& i_bsb) : |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 460 | BitString(i_bsb.getBitLen(), nullptr) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 461 | { |
| 462 | initBuffer(); |
Zane Shelley | 7f7a42d | 2019-10-28 13:28:31 -0500 | [diff] [blame] | 463 | if (!i_bsb.isZero()) |
| 464 | { |
| 465 | setString(i_bsb); |
| 466 | } |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 467 | } |
| 468 | |
| 469 | //------------------------------------------------------------------------------ |
| 470 | |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame] | 471 | BitStringBuffer& BitStringBuffer::operator=(const BitString& i_bs) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 472 | { |
| 473 | // The initBuffer() function will deallocate the buffer as well, however we |
| 474 | // also need to deallocate the buffer here before we set the length. |
Zane Shelley | 5a78fa8 | 2022-09-16 16:49:58 -0500 | [diff] [blame] | 475 | delete[] getBufAddr(); |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 476 | setBufAddr(nullptr); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 477 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 478 | setBitLen(i_bs.getBitLen()); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 479 | initBuffer(); |
Zane Shelley | 7f7a42d | 2019-10-28 13:28:31 -0500 | [diff] [blame] | 480 | if (!i_bs.isZero()) |
| 481 | { |
| 482 | setString(i_bs); |
| 483 | } |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 484 | |
| 485 | return *this; |
| 486 | } |
| 487 | |
| 488 | //------------------------------------------------------------------------------ |
| 489 | |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame] | 490 | BitStringBuffer& BitStringBuffer::operator=(const BitStringBuffer& i_bsb) |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 491 | { |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 492 | if (this != &i_bsb) // Check for assignment to self |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 493 | { |
| 494 | // The initBuffer() function will deallocate the buffer as well, however |
| 495 | // we also need to deallocate the buffer here before we set the length. |
Zane Shelley | 5a78fa8 | 2022-09-16 16:49:58 -0500 | [diff] [blame] | 496 | delete[] getBufAddr(); |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 497 | setBufAddr(nullptr); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 498 | |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 499 | setBitLen(i_bsb.getBitLen()); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 500 | initBuffer(); |
Zane Shelley | 7f7a42d | 2019-10-28 13:28:31 -0500 | [diff] [blame] | 501 | if (!i_bsb.isZero()) |
| 502 | { |
| 503 | setString(i_bsb); |
| 504 | } |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 505 | } |
| 506 | |
| 507 | return *this; |
| 508 | } |
| 509 | |
| 510 | //------------------------------------------------------------------------------ |
| 511 | |
| 512 | void BitStringBuffer::initBuffer() |
| 513 | { |
| 514 | // Deallocate the current buffer. |
Zane Shelley | 5a78fa8 | 2022-09-16 16:49:58 -0500 | [diff] [blame] | 515 | delete[] getBufAddr(); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 516 | |
Ben Tyner | a8126fd | 2019-08-01 19:40:07 -0500 | [diff] [blame] | 517 | // create new buffer, initialized to 0's |
Zane Shelley | c477199 | 2019-10-28 22:01:49 -0500 | [diff] [blame] | 518 | setBufAddr(new uint8_t[getMinBytes(getBitLen())]()); |
Zane Shelley | fd3f9cc | 2019-07-29 15:02:24 -0500 | [diff] [blame] | 519 | } |
| 520 | |
Zane Shelley | 871adec | 2019-07-30 11:01:39 -0500 | [diff] [blame] | 521 | } // end namespace libhei |