1 #ifndef ZSERIO_BIT_BUFFER_H_INC
2 #define ZSERIO_BIT_BUFFER_H_INC
31 template <
typename ALLOC = std::allocator<u
int8_t>>
35 static_assert(std::is_same<uint8_t, typename ALLOC::value_type>::value,
36 "Allocator with uint8_t value_type is required!");
47 return m_buffer.get_allocator();
115 explicit BasicBitBuffer(
const uint8_t* buffer,
size_t bitSize,
const ALLOC& allocator = ALLOC());
211 uint8_t getMaskedLastByte()
const;
217 template <
typename ALLOC>
223 template <
typename ALLOC>
229 template <
typename ALLOC>
231 m_buffer((bitSize + 7) / 8, 0, allocator),
235 template <
typename ALLOC>
237 m_buffer(buffer.begin(), buffer.end(), allocator),
238 m_bitSize(8 * buffer.size())
241 template <
typename ALLOC>
243 m_buffer(buffer.begin(), buffer.end(), allocator),
246 const size_t byteSize = (bitSize + 7) / 8;
247 if (buffer.
size() < byteSize)
250 << bitSize <<
" out of range for given span byte size " << buffer.
size() <<
"!";
254 template <
typename ALLOC>
256 m_buffer(std::move(buffer)),
257 m_bitSize(8 * m_buffer.size())
260 template <
typename ALLOC>
262 m_buffer(std::move(buffer)),
265 const size_t byteSize = (bitSize + 7) / 8;
266 if (m_buffer.size() < byteSize)
269 << bitSize <<
" out of range for given vector byte size " << m_buffer.size() <<
"!";
273 template <
typename ALLOC>
275 m_buffer(buffer, buffer + (bitSize + 7) / 8, allocator),
279 template <
typename ALLOC>
281 m_buffer(other.m_buffer, allocator),
282 m_bitSize(other.m_bitSize)
285 template <
typename ALLOC>
287 m_buffer(std::move(other.m_buffer), allocator),
288 m_bitSize(other.m_bitSize)
291 template <
typename ALLOC>
296 if (m_bitSize != other.m_bitSize)
301 const size_t byteSize = getByteSize();
306 if (memcmp(getBuffer(), other.
getBuffer(), byteSize - 1) != 0)
312 if (getMaskedLastByte() != other.getMaskedLastByte())
322 template <
typename ALLOC>
325 const size_t byteSize1 = getByteSize();
330 return byteSize2 != 0;
339 auto first1 = m_buffer.begin();
340 const auto last1 = first1 +
static_cast<difference_type
>(byteSize1 - 1);
341 auto first2 = other.m_buffer.begin();
342 const auto last2 = first2 +
static_cast<difference_type
>(byteSize2 - 1);
343 for (; (first1 != last1) && (first2 != last2); ++first1, ++first2)
345 if (*first1 < *first2)
349 if (*first2 < *first1)
355 const auto lastValue1 = first1 != last1 ? *first1 : getMaskedLastByte();
356 const auto lastValue2 = first2 != last2 ? *first2 : other.getMaskedLastByte();
357 if (lastValue1 < lastValue2)
361 if (lastValue2 < lastValue1)
366 return (first1 == last1) && (first2 != last2);
369 template <
typename ALLOC>
372 uint32_t result = ::zserio::HASH_SEED;
373 const size_t byteSize = getByteSize();
378 auto lastIt = m_buffer.begin() +
static_cast<int>(byteSize) - 1;
379 for (
auto it = m_buffer.begin(); it != lastIt; ++it)
390 template <
typename ALLOC>
393 return m_buffer.data();
396 template <
typename ALLOC>
399 return m_buffer.data();
402 template <
typename ALLOC>
408 template <
typename ALLOC>
411 return (m_bitSize + 7) / 8;
414 template <
typename ALLOC>
420 template <
typename ALLOC>
426 template <
typename ALLOC>
432 template <
typename ALLOC>
435 const size_t roundedByteSize = m_bitSize / 8;
436 const uint8_t lastByteBits =
static_cast<uint8_t
>(m_bitSize - 8 * roundedByteSize);
438 return (lastByteBits == 0)
439 ? m_buffer[roundedByteSize - 1]
440 :
static_cast<uint8_t
>(m_buffer[roundedByteSize] & (0xFFU << (8U - lastByteBits)));
454 template <
typename ALLOC>
457 return exception <<
"BitBuffer([...], " << bitBuffer.
getBitSize() <<
")";
BasicBitBuffer(vector< uint8_t, ALLOC > &&buffer)
size_t getByteSize() const
BasicBitBuffer(const BasicBitBuffer< ALLOC > &other, const ALLOC &allocator)
BasicBitBuffer & operator=(const BasicBitBuffer< ALLOC > &)=default
BasicBitBuffer(vector< uint8_t, ALLOC > &&buffer, size_t bitSize)
allocator_type get_allocator() const
BasicBitBuffer(const uint8_t *buffer, size_t bitSize, const ALLOC &allocator=ALLOC())
BasicBitBuffer(const BasicBitBuffer< ALLOC > &)=default
Span< const uint8_t > getData() const
size_t getBitSize() const
uint32_t hashCode() const
BasicBitBuffer & operator=(BasicBitBuffer< ALLOC > &&)=default
BasicBitBuffer(BasicBitBuffer< ALLOC > &&)=default
BasicBitBuffer(size_t bitSize, const ALLOC &allocator=ALLOC())
~BasicBitBuffer()=default
BasicBitBuffer(Span< const uint8_t > buffer, const ALLOC &allocator=ALLOC())
Span< uint8_t > getData()
const uint8_t * getBuffer() const
bool operator<(const BasicBitBuffer< ALLOC > &other) const
BasicBitBuffer(Span< const uint8_t > buffer, size_t bitSize, const ALLOC &allocator=ALLOC())
BasicBitBuffer(const ALLOC &allocator)
BasicBitBuffer(const BasicBitBuffer< ALLOC > &&other, const ALLOC &allocator)
bool operator==(const BasicBitBuffer< ALLOC > &other) const
const vector< uint8_t, ALLOC > & getBytes() const
constexpr size_type size() const noexcept
std::vector< T, RebindAlloc< ALLOC, T > > vector
CppRuntimeException & operator<<(CppRuntimeException &exception, const BasicBitBuffer< ALLOC > &bitBuffer)
std::enable_if< std::is_integral< T >::value &&(sizeof(T)<=4), uint32_t >::type calcHashCode(uint32_t seedValue, T value)