Audacity 3.2.0
BufferedStreamReader.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 BufferedStreamReader.cpp
6
7 Dmitry Vedenko
8
9**********************************************************************/
10
12
13#include <algorithm>
14#include <memory>
15#include <cstring>
16
18 : mBufferSize(std::max(bufferSize, RequiredAlignment))
19{
21
22 auto ptr = static_cast<void*>(mBufferData.data());
23 auto space = mBufferData.size();
24
25 std::align(RequiredAlignment, mBufferSize, ptr, space);
26
27 mBufferStart = static_cast<uint8_t*>(ptr);
28}
29
30size_t BufferedStreamReader::Read(void* buffer, size_t maxBytes)
31{
32 size_t bytesWritten = 0;
33
34 while (maxBytes > 0)
35 {
37 {
38 if (!HandleUnderflow())
39 return bytesWritten;
40 }
41
42 const size_t availableBytes = mCurrentBytes - mCurrentIndex;
43 const size_t bytesToRead = std::min(maxBytes, availableBytes);
44
45 std::memcpy(static_cast<uint8_t*>(buffer) + bytesWritten, mBufferStart + mCurrentIndex, bytesToRead);
46
47 maxBytes -= bytesToRead;
48 bytesWritten += bytesToRead;
49 mCurrentIndex += bytesToRead;
50 }
51
52 return bytesWritten;
53}
54
55bool BufferedStreamReader::Eof() const
56{
57 return mCurrentBytes == mCurrentIndex && !HasMoreData();
58}
59
60int BufferedStreamReader::GetC()
61{
62 uint8_t value = 0;
63
64 if (ReadValue(value))
65 return value;
66
67 return -1;
68}
69
70bool BufferedStreamReader::HandleUnderflow()
71{
72 if (!HasMoreData())
73 return false;
74
76 mCurrentIndex = 0;
77
78 return true;
79}
int min(int a, int b)
size_t Read(void *buffer, size_t maxBytes)
Read up to maxBytes into the buffer. Returns the number of bytes read.
static constexpr size_t RequiredAlignment
BufferedStreamReader(size_t bufferSize=4096)
std::enable_if_t< sizeof(ValueType)<=RequiredAlignment, bool > ReadValue(ValueType &value) { constexpr size_t valueSize=sizeof(ValueType);const size_t availableBytes=mCurrentBytes - mCurrentIndex;if(availableBytes< valueSize) return valueSize==Read(&value, valueSize);if constexpr(valueSize==1) value=mBufferStart[mCurrentIndex];else value=UncheckedRead< ValueType >();mCurrentIndex+=valueSize;return true;} bool Eof() const ;int GetC();protected:virtual bool HasMoreData() const=0;virtual size_t ReadData(void *buffer, size_t maxBytes)=0;private:bool HandleUnderflow();template< typename T > T UncheckedRead() noexcept { T result;if((mCurrentIndex % sizeof(T))==0) { const void *ptr=mBufferStart+mCurrentIndex;result=*static_cast< const T * >(ptr);} else { const uint8_t *begin=mBufferStart+mCurrentIndex;const uint8_t *end=begin+sizeof(T);void *out=&result;std::copy(begin, end, static_cast< uint8_t * >(out));} return result;} std::vector< uint8_t > mBufferData
Read a single value of ValueType, where sizeof(ValueType) <= 8 and value is aligned to the size bound...
STL namespace.