1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
/**********************************************************************
Audacity: A Digital Audio Editor
FifoBuffer.h
Dmitry Vedenko
**********************************************************************/
#include "FifoBuffer.h"
#include <algorithm>
FifoBuffer::Page::Page(int size)
: Data(size)
{
}
void FifoBuffer::Page::Reset()
{
WritePosition = 0;
ReadPosition = 0;
}
FifoBuffer::FifoBuffer(int pageSize)
: mPageSize { pageSize }
{
}
int64_t FifoBuffer::Write(const void* dataPtr, int64_t size)
{
const int8_t* data = static_cast<const int8_t*>(dataPtr);
auto bytesLeft = size;
while (bytesLeft > 0)
{
if (
mActivePages.empty() ||
mActivePages.back()->WritePosition == mPageSize)
{
if (mFreePages.empty())
{
mAllocatedPages.emplace_back(mPageSize);
mFreePages.push_back(&mAllocatedPages.back());
}
mActivePages.push(mFreePages.back());
mFreePages.pop_back();
}
auto& page = mActivePages.back();
auto toWrite = std::min(
bytesLeft, static_cast<int64_t>(mPageSize - page->WritePosition));
std::copy(data, data + toWrite, page->Data.begin() + page->WritePosition);
page->WritePosition += toWrite;
mAvaliable += toWrite;
data += toWrite;
bytesLeft -= toWrite;
}
return size;
}
int64_t FifoBuffer::Read(void* data, int64_t size)
{
size = std::min(size, mAvaliable);
int8_t* dataPtr = static_cast<int8_t*>(data);
int bytesRead = 0;
while (size > 0)
{
auto& page = mActivePages.front();
auto toRead =
std::min(size, static_cast<int64_t>(mPageSize - page->ReadPosition));
std::copy(
page->Data.begin() + page->ReadPosition,
page->Data.begin() + page->ReadPosition + toRead, dataPtr);
page->ReadPosition += toRead;
mAvaliable -= toRead;
dataPtr += toRead;
size -= toRead;
bytesRead += toRead;
if (page->ReadPosition == mPageSize)
{
page->Reset();
mFreePages.push_back(page);
mActivePages.pop();
}
}
return bytesRead;
}
int64_t FifoBuffer::GetAvailable() const
{
return mAvaliable;
}
|