2
#include <data_buffer.h>
7
uint8_t DataBufferBase::_dummy = 0;
9
DataChunk* DataChunk::GetNew(size_t size)
11
size_t sizeRequired = (size + sizeof(DataChunk) + 16) & ~0x0f;
12
void * ptr = new (std::nothrow) uint8_t[sizeRequired];
13
size_t storage = sizeRequired - sizeof(DataChunk);
16
uint8_t *data = (uint8_t *)ptr + sizeof(DataChunk);
18
DataChunk * dataChunk = new (ptr)DataChunk(data, size, storage);
22
DataChunk* DataChunk::GetNew(const void *data, size_t size)
24
DataChunk* buffer = GetNew(size);
27
memcpy(buffer->_data, data, size);
31
void DataChunk::Release(DataChunk * data)
33
// release only buffers created with GetNew
34
if(data->_data == reinterpret_cast<uint8_t*>(data) + sizeof(DataChunk) )
36
delete [] (uint8_t *)data;
40
void DataChunk::ReleaseRecursive(DataChunk * buffer)
45
next = buffer->Next();
46
DataChunk::Release(buffer);
51
DataChunk* DataChunk::Prev(DataChunk* first) const
55
if(first->Next() == this)
59
first = first->Next();
65
DataBufferBase::DataBufferBase()
73
DataBufferBase::DataBufferBase(DataBufferBase &&rhs) noexcept
76
_current = rhs._current;
83
DataBufferBase& DataBufferBase::operator=(DataBufferBase&& rhs) noexcept
87
_current = rhs._current;
96
DataBufferBase::~DataBufferBase()
101
void DataBufferBase::Clear()
103
DataChunk *buffer = _first;
104
_current = _first = 0;
105
DataChunk::ReleaseRecursive(buffer);
108
bool DataBufferBase::InsertFront(size_t size)
110
DataChunk* buffer = 0;
115
buffer = DataChunk::GetNew(size);
119
buffer->_next = next;
120
}while(!Atomic::CompareExchange(&_first, next, buffer));
125
DataChunk *DataChunk::FindLast(DataChunk *first)
131
first = first->Next();
137
bool DataBufferBase::InsertBack(size_t size)
139
DataChunk *last, *buffer = 0;
143
last = DataChunk::FindLast(_first);
144
pnext = last ? &(last->_next) : &_first;
147
uint16_t lastSize = last->Size();
148
if(last->Capacity() >= lastSize + size)
150
if(!Atomic::CompareExchange(&last->_size, lastSize, (uint16_t)(lastSize + size)))
153
DataChunk::Release(buffer);
158
buffer = DataChunk::GetNew(size);
161
}while(!Atomic::CompareExchange(pnext, (DataChunk *)0, buffer));
166
void DataBufferBase::AttachBack(DataChunk* buffer)
172
last = DataChunk::FindLast(_first);
173
pnext = last ? &(last->_next) : &_first;
174
}while(!Atomic::CompareExchange(pnext, (DataChunk *)0, buffer));
177
void DataBufferBase::AttachFront(DataChunk* buffer)
183
buffer->_next = next;
184
}while(!Atomic::CompareExchange(&_first, next, buffer));
187
DataChunk* DataBufferBase::DetachFront()
189
DataChunk* first, *next;
194
}while(!Atomic::CompareExchange(&_first, first, next));
199
bool DataBufferBase::Seek(size_t pos)
201
DataChunk *current = _first;
202
while(current && current->Size() <= pos)
204
pos -= current->Size();
205
current = current->Next();
216
size_t DataBufferBase::Tell()
218
DataChunk *current = _first;
219
size_t result = _pos;
221
while(current && current != _current)
223
result += current->Size();
224
current = current->Next();
229
size_t DataBufferBase::Size()
231
DataChunk *current = _first;
232
size_t totalSize = 0;
237
totalSize += current->Size();
238
current = current->Next();
244
unsigned DataBufferBase::Parts()
246
DataChunk *current = _first;
251
current = current->Next();