1 #ifndef ZSERIO_BIT_BUFFER_H_INC
2 #define ZSERIO_BIT_BUFFER_H_INC
30 template <
typename ALLOC = std::allocator<u
int8_t>>
34 static_assert(std::is_same<uint8_t, typename ALLOC::value_type>::value,
35 "Allocator with uint8_t value_type is required!");
46 return m_buffer.get_allocator();
114 explicit BasicBitBuffer(
const uint8_t* buffer,
size_t bitSize,
const ALLOC& allocator = ALLOC());
210 uint8_t getMaskedLastByte()
const;
216 template <
typename ALLOC>
222 template <
typename ALLOC>
228 template <
typename ALLOC>
230 m_buffer((bitSize + 7) / 8, 0, allocator),
234 template <
typename ALLOC>
236 m_buffer(buffer.begin(), buffer.end(), allocator),
237 m_bitSize(8 * buffer.size())
240 template <
typename ALLOC>
242 m_buffer(buffer.begin(), buffer.end(), allocator),
245 const size_t byteSize = (bitSize + 7) / 8;
246 if (buffer.
size() < byteSize)
249 << bitSize <<
" out of range for given span byte size " << buffer.
size() <<
"!";
253 template <
typename ALLOC>
255 m_buffer(std::move(buffer)),
256 m_bitSize(8 * m_buffer.size())
259 template <
typename ALLOC>
261 m_buffer(std::move(buffer)),
264 const size_t byteSize = (bitSize + 7) / 8;
265 if (m_buffer.size() < byteSize)
268 << bitSize <<
" out of range for given vector byte size " << m_buffer.size() <<
"!";
272 template <
typename ALLOC>
274 m_buffer(buffer, buffer + (bitSize + 7) / 8, allocator),
278 template <
typename ALLOC>
280 m_buffer(other.m_buffer, allocator),
281 m_bitSize(other.m_bitSize)
284 template <
typename ALLOC>
286 m_buffer(std::move(other.m_buffer), allocator),
287 m_bitSize(other.m_bitSize)
290 template <
typename ALLOC>
295 if (m_bitSize != other.m_bitSize)
300 const size_t byteSize = getByteSize();
305 if (memcmp(getBuffer(), other.
getBuffer(), byteSize - 1) != 0)
311 if (getMaskedLastByte() != other.getMaskedLastByte())
321 template <
typename ALLOC>
324 const size_t byteSize1 = getByteSize();
329 return byteSize2 != 0;
338 auto first1 = m_buffer.begin();
339 const auto last1 = first1 +
static_cast<difference_type
>(byteSize1 - 1);
340 auto first2 = other.m_buffer.begin();
341 const auto last2 = first2 +
static_cast<difference_type
>(byteSize2 - 1);
342 for (; (first1 != last1) && (first2 != last2); ++first1, ++first2)
344 if (*first1 < *first2)
348 if (*first2 < *first1)
354 const auto lastValue1 = first1 != last1 ? *first1 : getMaskedLastByte();
355 const auto lastValue2 = first2 != last2 ? *first2 : other.getMaskedLastByte();
356 if (lastValue1 < lastValue2)
360 if (lastValue2 < lastValue1)
365 return (first1 == last1) && (first2 != last2);
368 template <
typename ALLOC>
371 uint32_t result = ::zserio::HASH_SEED;
372 const size_t byteSize = getByteSize();
377 auto lastIt = m_buffer.begin() +
static_cast<int>(byteSize) - 1;
378 for (
auto it = m_buffer.begin(); it != lastIt; ++it)
389 template <
typename ALLOC>
392 return m_buffer.data();
395 template <
typename ALLOC>
398 return m_buffer.data();
401 template <
typename ALLOC>
407 template <
typename ALLOC>
410 return (m_bitSize + 7) / 8;
413 template <
typename ALLOC>
419 template <
typename ALLOC>
425 template <
typename ALLOC>
431 template <
typename ALLOC>
434 const size_t roundedByteSize = m_bitSize / 8;
435 const uint8_t lastByteBits =
static_cast<uint8_t
>(m_bitSize - 8 * roundedByteSize);
437 return (lastByteBits == 0)
438 ? m_buffer[roundedByteSize - 1]
439 :
static_cast<uint8_t
>(m_buffer[roundedByteSize] & (0xFFU << (8U - lastByteBits)));
453 template <
typename ALLOC>
456 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)