- Simple dynamic buffer class implementation.

- Will be used by the new (R5 compatible) NetBuffer class.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28918 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Bruno G. Albuquerque 2009-01-17 13:30:21 +00:00
parent cf4ef413b1
commit 550d24175f
2 changed files with 199 additions and 0 deletions

View File

@ -0,0 +1,60 @@
/*
* Copyright 2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Bruno Albuquerque, bga@bug-br.org.br
*/
#ifndef _DYNAMIC_BUFFER_H
#define _DYNAMIC_BUFFER_H
#include <SupportDefs.h>
class DynamicBuffer {
public:
DynamicBuffer(size_t _initialSize = 0);
~DynamicBuffer();
// InitCheck() should be called to guarantee the object initialization
// didn't fail. If it does not return B_OK, the initialization failed.
status_t InitCheck() const;
// Insert data at the end of the buffer. The buffer will be increased to
// accomodate the data if needed.
status_t Insert(const void* _data, size_t _size);
// Remove data from the start of the buffer. Move the buffer start
// pointer to point to the data following it.
status_t Remove(void* _data, size_t _size);
// Return a pointer to the underlying buffer. Note this will not
// necessarily be a pointer to the start of the allocated memory as the
// initial data may be positioned at an offset inside the buffer. In other
// words, this returns a pointer to the start of data inside the buffer.
unsigned char* Data() const;
// Returns the actual buffer size. This is the amount of memory allocated
// for the buffer.
size_t Size() const;
// Number of bytes of data still present in the buffer that can be
// extracted through calls to Remove().
size_t BytesRemaining() const;
// Dump some buffer statistics to stdout.
void PrintToStream();
private:
status_t _GrowToFit(size_t _size);
unsigned char* fBuffer;
size_t fBufferSize;
size_t fDataStart;
size_t fDataEnd;
status_t fInit;
};
#endif // _DYNAMIC_BUFFER_H

View File

@ -0,0 +1,139 @@
/*
* Copyright 2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Bruno Albuquerque, bga@bug-br.org.br
*/
#include "DynamicBuffer.h"
#include <Errors.h>
#include <SupportDefs.h>
DynamicBuffer::DynamicBuffer(size_t _initialSize) :
fBuffer(NULL),
fBufferSize(0),
fDataStart(0),
fDataEnd(0),
fInit(B_NO_INIT)
{
if (_initialSize > 0) {
fBuffer = new unsigned char[_initialSize];
if (fBuffer != NULL) {
fBufferSize = _initialSize;
fInit = B_OK;
}
}
}
DynamicBuffer::~DynamicBuffer()
{
delete[] fBuffer;
fBufferSize = 0;
fDataStart = 0;
fDataEnd = 0;
}
status_t
DynamicBuffer::InitCheck() const
{
return fInit;
}
status_t
DynamicBuffer::Insert(const void* _data, size_t _size)
{
if (fInit != B_OK)
return fInit;
status_t result = _GrowToFit(_size);
if (result != B_OK)
return result;
memcpy(fBuffer + fDataEnd, _data, _size);
fDataEnd += _size;
return B_OK;
}
status_t
DynamicBuffer::Remove(void* _data, size_t _size)
{
if (fInit != B_OK)
return fInit;
if (fDataStart + _size > fDataEnd)
return B_BUFFER_OVERFLOW;
memcpy(_data, fBuffer + fDataStart, _size);
fDataStart += _size;
if (fDataStart == fDataEnd)
fDataStart = fDataEnd = 0;
return B_OK;
}
unsigned char*
DynamicBuffer::Data() const
{
return fBuffer + fDataStart;
}
size_t
DynamicBuffer::Size() const
{
return fBufferSize;
}
size_t
DynamicBuffer::BytesRemaining() const
{
return fDataEnd - fDataStart;
}
void
DynamicBuffer::PrintToStream()
{
printf("Current buffer size : %ld\n", fBufferSize);
printf("Data start position : %ld\n", fDataStart);
printf("Data end position : %ld\n", fDataEnd);
printf("Bytes wasted : %ld\n", fDataStart);
printf("Bytes available : %ld\n", fBufferSize - fDataEnd);
}
status_t
DynamicBuffer::_GrowToFit(size_t _size)
{
if (_size <= fBufferSize - fDataEnd)
return B_OK;
size_t newSize = (fBufferSize + _size) * 2;
unsigned char* newBuffer = new unsigned char[newSize];
if (newBuffer == NULL)
return B_NO_MEMORY;
if (fDataStart != fDataEnd) {
memcpy(newBuffer, fBuffer + fDataStart, fDataEnd - fDataStart);
}
delete[] fBuffer;
fBuffer = newBuffer;
fDataEnd -= fDataStart;
fDataStart = 0;
fBufferSize = newSize;
return B_OK;
}