mirror of
https://github.com/Zygo/bees.git
synced 2025-05-17 21:35:45 +02:00
valgrind doesn't understand ioctl arguments, so it does not know if or when they initialize memory, and it complains about conditionals depending on data that comes out of ioctls. That's a problem for bees, where every decision we ever make is based on data an ioctl gave us. Fix the initialization issue by using calloc instead of malloc for ByteVectors when we are building for valgrind. Don't enable this by default because all the callocs aren't necessary (assuming the rest of the code is correct) and hurt performance. Define BEES_VALGRIND in localconf to activate, e.g. echo CCFLAGS += -DBEES_VALGRIND=1 >> localconf Signed-off-by: Zygo Blaxell <bees@furryterror.org>
148 lines
2.9 KiB
C++
148 lines
2.9 KiB
C++
#include "crucible/bytevector.h"
|
|
|
|
#include "crucible/error.h"
|
|
|
|
namespace crucible {
|
|
using namespace std;
|
|
|
|
ByteVector::iterator
|
|
ByteVector::begin() const
|
|
{
|
|
return m_ptr.get();
|
|
}
|
|
|
|
ByteVector::iterator
|
|
ByteVector::end() const
|
|
{
|
|
return m_ptr.get() + m_size;
|
|
}
|
|
|
|
size_t
|
|
ByteVector::size() const
|
|
{
|
|
return m_size;
|
|
}
|
|
|
|
bool
|
|
ByteVector::empty() const
|
|
{
|
|
return !m_ptr || !m_size;
|
|
}
|
|
|
|
void
|
|
ByteVector::clear()
|
|
{
|
|
m_ptr.reset();
|
|
m_size = 0;
|
|
}
|
|
|
|
ByteVector::value_type&
|
|
ByteVector::operator[](size_t size) const
|
|
{
|
|
return m_ptr.get()[size];
|
|
}
|
|
|
|
ByteVector::ByteVector(const ByteVector &that, size_t start, size_t length)
|
|
{
|
|
THROW_CHECK0(out_of_range, that.m_ptr);
|
|
THROW_CHECK2(out_of_range, start, that.m_size, start < that.m_size);
|
|
THROW_CHECK2(out_of_range, start + length, that.m_size + length, start + length < that.m_size + length);
|
|
m_ptr = Pointer(that.m_ptr, that.m_ptr.get() + start);
|
|
m_size = length;
|
|
}
|
|
|
|
ByteVector
|
|
ByteVector::at(size_t start, size_t length) const
|
|
{
|
|
return ByteVector(*this, start, length);
|
|
}
|
|
|
|
ByteVector::value_type&
|
|
ByteVector::at(size_t size) const
|
|
{
|
|
THROW_CHECK0(out_of_range, m_ptr);
|
|
THROW_CHECK2(out_of_range, size, m_size, size < m_size);
|
|
return m_ptr.get()[size];
|
|
}
|
|
|
|
static
|
|
void *
|
|
bv_allocate(size_t size)
|
|
{
|
|
#ifdef BEES_VALGRIND
|
|
// XXX: only do this to shut up valgrind
|
|
return calloc(1, size);
|
|
#else
|
|
return malloc(size);
|
|
#endif
|
|
}
|
|
|
|
ByteVector::ByteVector(size_t size)
|
|
{
|
|
m_ptr = Pointer(static_cast<value_type*>(bv_allocate(size)), free);
|
|
// bad_alloc doesn't fit THROW_CHECK's template
|
|
THROW_CHECK0(runtime_error, m_ptr);
|
|
m_size = size;
|
|
}
|
|
|
|
ByteVector::ByteVector(iterator begin, iterator end, size_t min_size)
|
|
{
|
|
const size_t size = end - begin;
|
|
const size_t alloc_size = max(size, min_size);
|
|
m_ptr = Pointer(static_cast<value_type*>(bv_allocate(alloc_size)), free);
|
|
THROW_CHECK0(runtime_error, m_ptr);
|
|
m_size = alloc_size;
|
|
memcpy(m_ptr.get(), begin, size);
|
|
}
|
|
|
|
bool
|
|
ByteVector::operator==(const ByteVector &that) const
|
|
{
|
|
if (!m_ptr) {
|
|
return !that.m_ptr;
|
|
}
|
|
if (!that.m_ptr) {
|
|
return false;
|
|
}
|
|
if (m_size != that.m_size) {
|
|
return false;
|
|
}
|
|
if (m_ptr.get() == that.m_ptr.get()) {
|
|
return true;
|
|
}
|
|
return !memcmp(m_ptr.get(), that.m_ptr.get(), m_size);
|
|
}
|
|
|
|
void
|
|
ByteVector::erase(iterator begin, iterator end)
|
|
{
|
|
const size_t size = end - begin;
|
|
if (!size) return;
|
|
THROW_CHECK0(out_of_range, m_ptr);
|
|
const iterator my_begin = m_ptr.get();
|
|
const iterator my_end = my_begin + m_size;
|
|
THROW_CHECK4(out_of_range, my_begin, begin, my_end, end, my_begin == begin || my_end == end);
|
|
if (begin == my_begin) {
|
|
if (end == my_end) {
|
|
m_size = 0;
|
|
m_ptr.reset();
|
|
return;
|
|
}
|
|
m_ptr = Pointer(m_ptr, end);
|
|
}
|
|
m_size -= size;
|
|
}
|
|
|
|
void
|
|
ByteVector::erase(iterator begin)
|
|
{
|
|
erase(begin, begin + 1);
|
|
}
|
|
|
|
ByteVector::value_type*
|
|
ByteVector::data() const
|
|
{
|
|
return m_ptr.get();
|
|
}
|
|
}
|