Rewrote MemBuffer to do some internal checks.

committer: mfx <mfx> 1042580463 +0000
This commit is contained in:
Markus F.X.J. Oberhumer 2003-01-14 21:41:03 +00:00
parent beb766b005
commit 03fb0d95c6
2 changed files with 66 additions and 50 deletions

View File

@ -35,10 +35,10 @@
**************************************************************************/
MemBuffer::MemBuffer(unsigned size) :
ptr(NULL), alloc_ptr(NULL), alloc_size(0)
ptr(NULL), psize(0)
{
if (size > 0)
alloc(size, 0);
alloc(size);
}
@ -49,44 +49,13 @@ MemBuffer::~MemBuffer()
void MemBuffer::dealloc()
{
if (alloc_ptr)
::free(alloc_ptr);
alloc_ptr = ptr = NULL;
alloc_size = 0;
}
unsigned MemBuffer::getSize() const
{
if (!alloc_ptr)
return 0;
unsigned size = alloc_size - (ptr - alloc_ptr);
assert((int)size > 0);
return size;
}
void MemBuffer::alloc(unsigned size, unsigned base_offset)
{
// NOTE: we don't automaticlly free a used buffer
assert(alloc_ptr == NULL);
assert((int)size > 0);
size = base_offset + size;
alloc_ptr = (unsigned char *) malloc(size);
if (!alloc_ptr)
if (ptr)
{
//throw bad_alloc();
throwCantPack("out of memory");
//exit(1);
checkState();
::free(ptr - 8);
}
alloc_size = size;
ptr = alloc_ptr + base_offset;
}
void MemBuffer::alloc(unsigned size)
{
alloc(size, 0);
ptr = NULL;
psize = 0;
}
@ -94,7 +63,7 @@ void MemBuffer::allocForCompression(unsigned uncompressed_size, unsigned extra)
{
assert((int)uncompressed_size > 0);
assert((int)extra >= 0);
alloc(uncompressed_size + uncompressed_size/8 + 256 + extra, 0);
alloc(uncompressed_size + uncompressed_size/8 + 256 + extra);
}
@ -102,8 +71,58 @@ void MemBuffer::allocForUncompression(unsigned uncompressed_size, unsigned extra
{
assert((int)uncompressed_size > 0);
assert((int)extra >= 0);
//alloc(uncompressed_size + 3 + 512 + extra, 0); // 512 safety bytes
alloc(uncompressed_size + 3 + extra, 0); // 3 bytes for asm_fast decompresion
// note: 3 bytes are allowed overrun for the asm_fast decompressors
// alloc(uncompressed_size + 3 + 512 + extra); // 512 safety bytes
alloc(uncompressed_size + 3 + extra);
}
/*************************************************************************
//
**************************************************************************/
#define MAGIC1(p) ((unsigned)(p) ^ 0xfefdbeeb)
#define MAGIC2(p) ((unsigned)(p) ^ 0xfefdbeeb ^ 0x80024001)
unsigned MemBuffer::global_alloc_counter = 0;
void MemBuffer::checkState() const
{
if (!ptr)
throwInternalError("block not allocated");
if (get_be32(ptr - 4) != MAGIC1(ptr))
throwInternalError("memory clobbered before allocated block 1");
if (get_be32(ptr - 8) != psize)
throwInternalError("memory clobbered before allocated block 2");
if (get_be32(ptr + psize) != MAGIC2(ptr))
throwInternalError("memory clobbered past end of allocated block");
}
void MemBuffer::alloc(unsigned size)
{
// NOTE: we don't automaticlly free a used buffer
assert(ptr == NULL);
assert(psize == 0);
//
assert((int)size > 0);
unsigned total = 4 + 4 + size + 4 + 4;
assert((int)total > 0);
unsigned char *p = (unsigned char *) malloc(total);
if (!p)
{
//throw bad_alloc();
throwCantPack("out of memory");
//exit(1);
}
ptr = p + 8;
psize = size;
// store magic state
set_be32(ptr - 8, psize);
set_be32(ptr - 4, MAGIC1(ptr));
set_be32(ptr + psize, MAGIC2(ptr));
set_be32(ptr + psize + 4, global_alloc_counter++);
}

View File

@ -46,24 +46,21 @@ public:
void dealloc();
const unsigned char *getBuf() const { return ptr; }
unsigned getSize() const;
void checkState() const;
unsigned getSize() const { return psize; }
operator unsigned char * () { return ptr; }
//operator const unsigned char * () const { return ptr; }
const unsigned char *getBuf() const { return ptr; }
void *getVoidPtr() { return (void *) ptr; }
const void *getVoidPtr() const { return (const void *) ptr; }
private:
void alloc(unsigned size, unsigned base_offset);
protected:
unsigned char *ptr;
unsigned char *alloc_ptr;
unsigned alloc_size;
unsigned psize;
static unsigned global_alloc_counter;
private:
// disable copy and assignment
MemBuffer(MemBuffer const &); // {}
MemBuffer& operator= (MemBuffer const &); // { return *this; }