1 #ifndef ZSERIO_BIT_BUFFER_H_INC
2 #define ZSERIO_BIT_BUFFER_H_INC
34 template <
typename ALLOC = std::allocator<u
int8_t>>
38 static_assert(std::is_same<uint8_t, typename ALLOC::value_type>::value,
39 "Allocator with uint8_t value_type is required!");
50 return m_buffer.get_allocator();
154 return !(*
this == other);
175 return other < *
this;
187 return !(other < *
this);
199 return !(*
this < other);
244 const std::vector<uint8_t, ALLOC>&
getBytes()
const;
261 uint8_t getMaskedLastByte()
const;
263 std::vector<uint8_t, ALLOC> m_buffer;
267 template <
typename ALLOC>
273 template <
typename ALLOC>
279 template <
typename ALLOC>
281 m_buffer((bitSize + 7) / 8, 0, allocator),
285 template <
typename ALLOC>
287 m_buffer(buffer.begin(), buffer.end(), allocator),
288 m_bitSize(8 * buffer.size())
291 template <
typename ALLOC>
293 m_buffer(buffer.begin(), buffer.end(), allocator),
296 const size_t byteSize = (bitSize + 7) / 8;
297 if (buffer.
size() < byteSize)
300 << bitSize <<
" out of range for given span byte size " << buffer.
size() <<
"!";
304 template <
typename ALLOC>
306 m_buffer(
std::move(buffer)),
307 m_bitSize(8 * m_buffer.size())
310 template <
typename ALLOC>
312 m_buffer(
std::move(buffer)),
315 const size_t byteSize = (bitSize + 7) / 8;
316 if (m_buffer.size() < byteSize)
319 << bitSize <<
" out of range for given vector byte size " << m_buffer.size() <<
"!";
323 template <
typename ALLOC>
325 m_buffer(other.m_buffer, allocator),
326 m_bitSize(other.m_bitSize)
329 template <
typename ALLOC>
331 m_buffer(
std::move(other.m_buffer), allocator),
332 m_bitSize(other.m_bitSize)
335 template <
typename ALLOC>
340 if (m_bitSize != other.m_bitSize)
345 const size_t byteSize = getByteSize();
350 if (std::memcmp(getBuffer(), other.
getBuffer(), byteSize - 1) != 0)
356 if (getMaskedLastByte() != other.getMaskedLastByte())
366 template <
typename ALLOC>
369 const size_t byteSize1 = getByteSize();
374 return byteSize2 != 0;
381 using DifferenceType =
typename std::vector<uint8_t, ALLOC>::iterator::difference_type;
383 auto first1 = m_buffer.begin();
384 const auto last1 = first1 +
static_cast<DifferenceType
>(byteSize1 - 1);
385 auto first2 = other.m_buffer.begin();
386 const auto last2 = first2 +
static_cast<DifferenceType
>(byteSize2 - 1);
387 for (; (first1 != last1) && (first2 != last2); ++first1, ++first2)
389 if (*first1 < *first2)
393 if (*first2 < *first1)
399 const auto lastValue1 = first1 != last1 ? *first1 : getMaskedLastByte();
400 const auto lastValue2 = first2 != last2 ? *first2 : other.getMaskedLastByte();
401 if (lastValue1 < lastValue2)
405 if (lastValue2 < lastValue1)
410 return (first1 == last1) && (first2 != last2);
413 template <
typename ALLOC>
416 uint32_t result = HASH_SEED;
417 const size_t byteSize = getByteSize();
422 auto lastIt = m_buffer.begin() +
static_cast<int>(byteSize) - 1;
423 for (
auto it = m_buffer.begin(); it != lastIt; ++it)
434 template <
typename ALLOC>
437 return m_buffer.data();
440 template <
typename ALLOC>
443 return m_buffer.data();
446 template <
typename ALLOC>
452 template <
typename ALLOC>
455 return (m_bitSize + 7) / 8;
458 template <
typename ALLOC>
464 template <
typename ALLOC>
470 template <
typename ALLOC>
476 template <
typename ALLOC>
479 const size_t roundedByteSize = m_bitSize / 8;
480 const uint8_t lastByteBits =
static_cast<uint8_t
>(m_bitSize - 8 * roundedByteSize);
482 return (lastByteBits == 0)
483 ? m_buffer[roundedByteSize - 1]
484 :
static_cast<uint8_t
>(m_buffer[roundedByteSize] & (0xFFU << (8U - lastByteBits)));
491 template <
typename ALLOC>
497 template <
typename ALLOC>
506 template <
typename ALLOC>
509 return lhs.get() == rhs.get();
512 template <
typename ALLOC>
515 return lhs.get() != rhs.get();
518 template <
typename ALLOC>
521 return lhs.get() < rhs.get();
524 template <
typename ALLOC>
527 return lhs.get() > rhs.get();
530 template <
typename ALLOC>
533 return lhs.get() <= rhs.get();
536 template <
typename ALLOC>
539 return lhs.get() >= rhs.get();
552 template <
typename ALLOC>
555 return exception <<
"BitBuffer([...], " << bitBuffer.
getBitSize() <<
")";
566 template <
typename ALLOC>
575 template <
typename ALLOC>
576 void validate(
const BasicBitBufferView<ALLOC>&, std::string_view)
581 template <
typename ALLOC>
582 BitSize bitSizeOf(
const BasicBitBufferView<ALLOC>& bitBufferView,
BitSize = 0)
584 const BasicBitBuffer<ALLOC>& bitBuffer = bitBufferView.get();
588 return bitSizeOf(bitBufferSize) + bitBufferSize;
591 template <
typename ALLOC>
592 BitSize initializeOffsets(
const BasicBitBufferView<ALLOC>& bitBufferView,
BitSize bitPosition)
594 return bitSizeof(bitBufferView, bitPosition);
607 template <
typename ALLOC>
608 struct hash<
zserio::BasicBitBuffer<ALLOC>>
612 return static_cast<size_t>(bitBuffer.
hashCode());
619 template <
typename ALLOC>
624 return static_cast<size_t>(bitBuffer.get().hashCode());
size_t getByteSize() const
BasicBitBuffer(const BasicBitBuffer &other, const ALLOC &allocator)
ALLOC get_allocator() const
bool operator<=(const BasicBitBuffer &other) const
BasicBitBuffer(std::vector< uint8_t, ALLOC > &&buffer)
BasicBitBuffer(Span< const uint8_t > buffer, const ALLOC &allocator={})
BasicBitBuffer & operator=(BasicBitBuffer &&)=default
bool operator>(const BasicBitBuffer &other) const
BasicBitBuffer(BasicBitBuffer &&)=default
BasicBitBuffer(const BasicBitBuffer &)=default
Span< const uint8_t > getData() const
size_t getBitSize() const
uint32_t hashCode() const
BasicBitBuffer(size_t bitSize, const ALLOC &allocator={})
BasicBitBuffer(std::vector< uint8_t, ALLOC > &&buffer, size_t bitSize)
bool operator>=(const BasicBitBuffer &other) const
bool operator==(const BasicBitBuffer &other) const
bool operator<(const BasicBitBuffer &other) const
BasicBitBuffer & operator=(const BasicBitBuffer &)=default
~BasicBitBuffer()=default
const std::vector< uint8_t, ALLOC > & getBytes() const
Span< uint8_t > getData()
const uint8_t * getBuffer() const
BasicBitBuffer(const ALLOC &allocator)
BasicBitBuffer(Span< const uint8_t > buffer, size_t bitSize, const ALLOC &allocator={})
bool operator!=(const BasicBitBuffer &other) const
BasicBitBuffer(BasicBitBuffer &&other, const ALLOC &allocator)
constexpr size_type size() const noexcept
bool operator>(const BasicBitBufferView< ALLOC > &lhs, const BasicBitBufferView< ALLOC > &rhs)
bool operator==(const BasicBitBufferView< ALLOC > &lhs, const BasicBitBufferView< ALLOC > &rhs)
std::reference_wrapper< const BitBuffer > BitBufferView
bool operator<(const BasicBitBufferView< ALLOC > &lhs, const BasicBitBufferView< ALLOC > &rhs)
uint32_t calcHashCode(uint32_t seedValue, const ArrayView< T, ARRAY_TRAITS > &array)
CppRuntimeException & operator<<(CppRuntimeException &exception, const BasicBitBuffer< ALLOC > &bitBuffer)
uint32_t convertSizeToUInt32(size_t value)
bool operator<=(const BasicBitBufferView< ALLOC > &lhs, const BasicBitBufferView< ALLOC > &rhs)
bool operator>=(const BasicBitBufferView< ALLOC > &lhs, const BasicBitBufferView< ALLOC > &rhs)
std::reference_wrapper< const BasicBitBuffer< ALLOC > > BasicBitBufferView
bool operator!=(const BasicBitBufferView< ALLOC > &lhs, const BasicBitBufferView< ALLOC > &rhs)
detail::VarIntWrapper< uint32_t, detail::VarIntType::VARSIZE > VarSize
size_t operator()(const zserio::BasicBitBufferView< ALLOC > &bitBuffer) const
size_t operator()(const zserio::BasicBitBuffer< ALLOC > &bitBuffer) const
BasicBitBufferView< ALLOC > type