Add stream buffering (WIP)
This commit is contained in:
@@ -32,15 +32,6 @@ namespace Nz
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the position of the cursor (which is always zero)
|
||||
* \return Always zero
|
||||
*/
|
||||
UInt64 EmptyStream::GetCursorPos() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the size of the raw memory (how many bytes would have been written on a regular stream)
|
||||
* \return Size occupied until now
|
||||
@@ -50,17 +41,6 @@ namespace Nz
|
||||
return m_size;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Does nothing
|
||||
* \return true
|
||||
*
|
||||
* \param offset Offset according to the beginning of the stream
|
||||
*/
|
||||
bool EmptyStream::SetCursorPos(UInt64 /*offset*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Flushes the stream (does nothing)
|
||||
*/
|
||||
@@ -83,6 +63,26 @@ namespace Nz
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Does nothing
|
||||
* \return true
|
||||
*
|
||||
* \param offset Offset according to the beginning of the stream
|
||||
*/
|
||||
bool EmptyStream::SeekStreamCursor(UInt64 /*offset*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the position of the cursor (which is always zero)
|
||||
* \return Always zero
|
||||
*/
|
||||
UInt64 EmptyStream::TellStreamCursor() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Writes data
|
||||
* \return size
|
||||
|
||||
@@ -154,20 +154,6 @@ namespace Nz
|
||||
return std::filesystem::exists(m_filePath);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the position of the cursor in the file
|
||||
* \return Position of the cursor
|
||||
*
|
||||
* \remark Produces a NazaraAssert if file is not open
|
||||
*/
|
||||
|
||||
UInt64 File::GetCursorPos() const
|
||||
{
|
||||
NazaraAssert(IsOpen(), "File is not open");
|
||||
|
||||
return m_impl->GetCursorPos();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the directory of the file
|
||||
* \return Directory of the file
|
||||
@@ -240,6 +226,8 @@ namespace Nz
|
||||
m_openMode = openMode;
|
||||
m_impl = std::move(impl);
|
||||
|
||||
EnableBuffering(!m_openMode.Test(OpenMode::Unbuffered));
|
||||
|
||||
if (m_openMode & OpenMode::Text)
|
||||
m_streamOptions |= StreamOption::Text;
|
||||
else
|
||||
@@ -266,39 +254,6 @@ namespace Nz
|
||||
return Open(openMode);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the position of the cursor
|
||||
* \return true if cursor is successfully positioned
|
||||
*
|
||||
* \param pos Position of the cursor
|
||||
* \param offset Offset according to the cursor position
|
||||
*
|
||||
* \remark Produces a NazaraAssert if file is not open
|
||||
*/
|
||||
|
||||
bool File::SetCursorPos(CursorPosition pos, Int64 offset)
|
||||
{
|
||||
NazaraAssert(IsOpen(), "File is not open");
|
||||
|
||||
return m_impl->SetCursorPos(pos, offset);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the position of the cursor
|
||||
* \return true if cursor is successfully positioned
|
||||
*
|
||||
* \param offset Offset according to the cursor begin position
|
||||
*
|
||||
* \remark Produces a NazaraAssert if file is not open
|
||||
*/
|
||||
|
||||
bool File::SetCursorPos(UInt64 offset)
|
||||
{
|
||||
NazaraAssert(IsOpen(), "File is not open");
|
||||
|
||||
return m_impl->SetCursorPos(CursorPosition::AtBegin, offset);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the file path
|
||||
* \return true if file opening is successful
|
||||
@@ -389,6 +344,35 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the position of the cursor
|
||||
* \return true if cursor is successfully positioned
|
||||
*
|
||||
* \param offset Offset according to the cursor begin position
|
||||
*
|
||||
* \remark Produces a NazaraAssert if file is not open
|
||||
*/
|
||||
|
||||
bool File::SeekStreamCursor(UInt64 offset)
|
||||
{
|
||||
NazaraAssert(IsOpen(), "File is not open");
|
||||
|
||||
return m_impl->SetCursorPos(CursorPosition::AtBegin, offset);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the position of the cursor in the file
|
||||
* \return Position of the cursor
|
||||
*
|
||||
* \remark Produces a NazaraAssert if file is not open
|
||||
*/
|
||||
UInt64 File::TellStreamCursor() const
|
||||
{
|
||||
NazaraAssert(IsOpen(), "File is not open");
|
||||
|
||||
return m_impl->GetCursorPos();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Writes blocks
|
||||
* \return Number of blocks written
|
||||
|
||||
@@ -36,16 +36,6 @@ namespace Nz
|
||||
return m_pos >= m_buffer->size();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the position of the cursor
|
||||
* \return Position of the cursor
|
||||
*/
|
||||
|
||||
UInt64 MemoryStream::GetCursorPos() const
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the size of the raw memory
|
||||
* \return Size of the memory
|
||||
@@ -73,20 +63,6 @@ namespace Nz
|
||||
m_openMode = openMode;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the position of the cursor
|
||||
* \return true
|
||||
*
|
||||
* \param offset Offset according to the beginning of the stream
|
||||
*/
|
||||
|
||||
bool MemoryStream::SetCursorPos(UInt64 offset)
|
||||
{
|
||||
m_pos = offset;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Flushes the stream
|
||||
*/
|
||||
@@ -118,6 +94,28 @@ namespace Nz
|
||||
return readSize;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the position of the cursor
|
||||
* \return true
|
||||
*
|
||||
* \param offset Offset according to the beginning of the stream
|
||||
*/
|
||||
bool MemoryStream::SeekStreamCursor(UInt64 offset)
|
||||
{
|
||||
m_pos = offset;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the position of the cursor
|
||||
* \return Position of the cursor
|
||||
*/
|
||||
UInt64 MemoryStream::TellStreamCursor() const
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Writes blocks
|
||||
* \return Number of blocks written
|
||||
@@ -127,7 +125,6 @@ namespace Nz
|
||||
*
|
||||
* \remark Produces a NazaraAssert if buffer is nullptr
|
||||
*/
|
||||
|
||||
std::size_t MemoryStream::WriteBlock(const void* buffer, std::size_t size)
|
||||
{
|
||||
if (size > 0)
|
||||
|
||||
@@ -59,16 +59,6 @@ namespace Nz
|
||||
return m_pos >= m_size;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the position of the cursor
|
||||
* \return Position of the cursor
|
||||
*/
|
||||
|
||||
UInt64 MemoryView::GetCursorPos() const
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the size of the raw memory
|
||||
* \return Size of the memory
|
||||
@@ -79,20 +69,6 @@ namespace Nz
|
||||
return m_size;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the position of the cursor
|
||||
* \return true
|
||||
*
|
||||
* \param offset Offset according to the beginning of the stream
|
||||
*/
|
||||
|
||||
bool MemoryView::SetCursorPos(UInt64 offset)
|
||||
{
|
||||
m_pos = std::min(offset, m_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Flushes the stream
|
||||
*/
|
||||
@@ -121,6 +97,28 @@ namespace Nz
|
||||
return readSize;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the position of the cursor
|
||||
* \return true
|
||||
*
|
||||
* \param offset Offset according to the beginning of the stream
|
||||
*/
|
||||
bool MemoryView::SeekStreamCursor(UInt64 offset)
|
||||
{
|
||||
m_pos = std::min(offset, m_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the position of the cursor
|
||||
* \return Position of the cursor
|
||||
*/
|
||||
UInt64 MemoryView::TellStreamCursor() const
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Writes blocks
|
||||
* \return Number of blocks written
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Nz
|
||||
|
||||
std::filesystem::path Stream::GetDirectory() const
|
||||
{
|
||||
return std::filesystem::path();
|
||||
return {};
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -40,7 +40,81 @@ namespace Nz
|
||||
|
||||
std::filesystem::path Stream::GetPath() const
|
||||
{
|
||||
return std::filesystem::path();
|
||||
return {};
|
||||
}
|
||||
|
||||
UInt64 Stream::GetCursorPos() const
|
||||
{
|
||||
if (m_bufferCapacity == 0)
|
||||
return TellStreamCursor();
|
||||
else
|
||||
{
|
||||
assert(m_bufferCursor >= m_bufferSize);
|
||||
return m_bufferCursor - m_bufferSize + m_bufferOffset;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reads the stream and puts the result in a buffer
|
||||
* \return Size of the read
|
||||
*
|
||||
* \param buffer Buffer to stock data
|
||||
* \param size Size meant to be read
|
||||
*
|
||||
* \remark Produces a NazaraAssert if stream is not readable
|
||||
* \remark If preallocated space of buffer is less than the size, the behavior is undefined
|
||||
*/
|
||||
std::size_t Stream::Read(void* buffer, std::size_t size)
|
||||
{
|
||||
NazaraAssert(IsReadable(), "Stream is not readable");
|
||||
|
||||
if (m_bufferCapacity == 0)
|
||||
return ReadBlock(buffer, size);
|
||||
|
||||
UInt8* ptr = static_cast<UInt8*>(buffer);
|
||||
|
||||
std::size_t readSize = 0;
|
||||
if (m_bufferOffset < m_bufferSize)
|
||||
{
|
||||
std::size_t availableSize = std::min(size, m_bufferSize - m_bufferOffset);
|
||||
if (ptr)
|
||||
{
|
||||
std::memcpy(ptr, &m_buffer[m_bufferOffset], availableSize);
|
||||
ptr += availableSize;
|
||||
}
|
||||
|
||||
m_bufferOffset += availableSize;
|
||||
readSize += availableSize;
|
||||
size -= availableSize;
|
||||
}
|
||||
|
||||
if (size > m_bufferCapacity)
|
||||
{
|
||||
// Unbuffered read
|
||||
m_bufferSize = 0;
|
||||
std::size_t blockSize = ReadBlock(ptr, size);
|
||||
m_bufferCursor += blockSize;
|
||||
readSize += blockSize;
|
||||
}
|
||||
else if (size > 0)
|
||||
{
|
||||
m_bufferOffset = 0;
|
||||
m_bufferSize = ReadBlock(&m_buffer[0], m_bufferCapacity);
|
||||
m_bufferCursor += m_bufferSize;
|
||||
|
||||
std::size_t remainingSize = std::min(m_bufferSize, size);
|
||||
if (ptr)
|
||||
{
|
||||
std::memcpy(ptr, &m_buffer[m_bufferOffset], remainingSize);
|
||||
ptr += remainingSize;
|
||||
}
|
||||
|
||||
m_bufferOffset += remainingSize;
|
||||
readSize += remainingSize;
|
||||
size -= remainingSize;
|
||||
}
|
||||
|
||||
return readSize;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -147,19 +147,6 @@ namespace Nz
|
||||
return QueryAvailableBytes() == 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the position of the cursor
|
||||
* \return 0
|
||||
*
|
||||
* \remark Produces a NazaraError because it is a special stream
|
||||
*/
|
||||
|
||||
UInt64 TcpClient::GetCursorPos() const
|
||||
{
|
||||
NazaraError("GetCursorPos() cannot be used on sequential streams");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the size of the raw memory available
|
||||
* \return Size of the memory available
|
||||
@@ -456,21 +443,6 @@ namespace Nz
|
||||
return Send(ptr, size, nullptr);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the position of the cursor
|
||||
* \return false
|
||||
*
|
||||
* \param offset Offset according to the beginning of the stream
|
||||
*
|
||||
* \remark Produces a NazaraError because it is a special stream
|
||||
*/
|
||||
|
||||
bool TcpClient::SetCursorPos(UInt64 /*offset*/)
|
||||
{
|
||||
NazaraError("SetCursorPos() cannot be used on sequential streams");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Waits for being connected before time out
|
||||
* \return The new socket state, either Connected if connection did succeed or NotConnected if an error occurred
|
||||
@@ -605,6 +577,32 @@ namespace Nz
|
||||
UpdateState(SocketState::Connected);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the position of the cursor
|
||||
* \return false
|
||||
*
|
||||
* \param offset Offset according to the beginning of the stream
|
||||
*
|
||||
* \remark Produces a NazaraError because it is a special stream
|
||||
*/
|
||||
bool TcpClient::SeekStreamCursor(UInt64 /*offset*/)
|
||||
{
|
||||
NazaraError("SeekStreamCursor() cannot be used on sequential streams");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the position of the cursor
|
||||
* \return 0
|
||||
*
|
||||
* \remark Produces a NazaraError because it is a special stream
|
||||
*/
|
||||
UInt64 TcpClient::TellStreamCursor() const
|
||||
{
|
||||
NazaraError("TellStreamCursor() cannot be used on sequential streams");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Writes blocks
|
||||
* \return Number of blocks written
|
||||
|
||||
Reference in New Issue
Block a user