Files

89 lines
1.7 KiB
C++
Raw Permalink Normal View History

// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
2024-07-30 13:42:36 +02:00
// SPDX-License-Identifier: GPL-3.0+
2020-11-02 23:41:01 +01:00
#include "ringbuffer.h"
#include <cstring>
#include <cassert>
2024-01-27 15:20:14 +10:00
#include <algorithm>
2024-01-27 15:20:14 +10:00
RingBuffer::RingBuffer() = default;
2020-11-02 23:42:03 +01:00
RingBuffer::RingBuffer(size_t capacity)
: RingBuffer()
{
2024-01-27 15:20:14 +10:00
reset(capacity);
}
2024-01-27 15:20:14 +10:00
RingBuffer::~RingBuffer() = default;
2024-01-27 15:20:14 +10:00
void RingBuffer::reset(size_t capacity)
{
2024-01-27 15:20:14 +10:00
m_rpos = 0;
m_wpos = 0;
m_full = false;
m_data.reset();
if ((m_capacity = capacity) > 0)
m_data = std::make_unique<uint8_t[]>(capacity);
}
size_t RingBuffer::size() const
{
2024-01-27 15:20:14 +10:00
if (m_wpos == m_rpos)
return m_full ? m_capacity : 0;
else if (m_wpos > m_rpos)
return m_wpos - m_rpos;
else
2024-01-27 15:20:14 +10:00
return (m_capacity - m_rpos) + m_wpos;
}
2024-01-27 15:20:14 +10:00
size_t RingBuffer::read(void* dst, size_t nbytes)
{
2024-01-27 15:20:14 +10:00
uint8_t* bdst = static_cast<uint8_t*>(dst);
size_t to_read = nbytes;
2024-01-27 15:20:14 +10:00
while (to_read > 0)
{
2024-01-27 15:20:14 +10:00
size_t available;
if (m_wpos == m_rpos)
available = m_full ? (m_capacity - m_rpos) : 0;
else if (m_wpos > m_rpos)
available = m_wpos - m_rpos;
else
available = m_capacity - m_rpos;
if (available == 0)
break;
const size_t copy = std::min(available, to_read);
std::memcpy(bdst, m_data.get() + m_rpos, copy);
bdst += copy;
to_read -= copy;
m_rpos = (m_rpos + copy) % m_capacity;
m_full = false;
}
2024-01-27 15:20:14 +10:00
return nbytes - to_read;
}
2024-01-27 15:20:14 +10:00
void RingBuffer::write(const void* src, size_t nbytes)
{
2024-01-27 15:20:14 +10:00
const uint8_t* bsrc = static_cast<const uint8_t*>(src);
while (nbytes > 0)
{
2024-01-27 15:20:14 +10:00
size_t free;
if (m_wpos >= m_rpos)
free = m_capacity - m_wpos;
else
2024-01-27 15:20:14 +10:00
free = m_rpos - m_wpos;
2024-01-27 15:20:14 +10:00
const size_t copy = std::min(free, nbytes);
std::memcpy(m_data.get() + m_wpos, bsrc, copy);
bsrc += copy;
nbytes -= copy;
2024-01-27 15:20:14 +10:00
m_wpos = (m_wpos + copy) % m_capacity;
m_full = m_full || (m_wpos == m_rpos);
}
}