From 6352e8e3196f78388b6c771073f9e03eaa612673 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 20 Jun 2023 14:33:09 +1000 Subject: everything everywhere all at once --- source/core/StarBuffer.cpp | 287 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 source/core/StarBuffer.cpp (limited to 'source/core/StarBuffer.cpp') diff --git a/source/core/StarBuffer.cpp b/source/core/StarBuffer.cpp new file mode 100644 index 0000000..fbed59a --- /dev/null +++ b/source/core/StarBuffer.cpp @@ -0,0 +1,287 @@ +#include "StarBuffer.hpp" +#include "StarMathCommon.hpp" +#include "StarIODevice.hpp" +#include "StarFormat.hpp" + +namespace Star { + +Buffer::Buffer() + : m_pos(0) { + setMode(IOMode::ReadWrite); +} + +Buffer::Buffer(size_t initialSize) + : Buffer() { + reset(initialSize); +} + +Buffer::Buffer(ByteArray b) + : Buffer() { + reset(move(b)); +} + +Buffer::Buffer(Buffer const& buffer) + : Buffer() { + operator=(buffer); +} + +Buffer::Buffer(Buffer&& buffer) + : Buffer() { + operator=(move(buffer)); +} + +StreamOffset Buffer::pos() { + return m_pos; +} + +void Buffer::seek(StreamOffset pos, IOSeek mode) { + StreamOffset newPos = m_pos; + if (mode == IOSeek::Absolute) + newPos = pos; + else if (mode == IOSeek::Relative) + newPos += pos; + else if (mode == IOSeek::End) + newPos = m_bytes.size() - pos; + m_pos = newPos; +} + +void Buffer::resize(StreamOffset size) { + data().resize((size_t)size); +} + +bool Buffer::atEnd() { + return m_pos >= m_bytes.size(); +} + +size_t Buffer::read(char* data, size_t len) { + size_t l = doRead(m_pos, data, len); + m_pos += l; + return l; +} + +size_t Buffer::write(char const* data, size_t len) { + size_t l = doWrite(m_pos, data, len); + m_pos += l; + return l; +} + +size_t Buffer::readAbsolute(StreamOffset readPosition, char* data, size_t len) { + size_t rpos = readPosition; + if ((StreamOffset)rpos != readPosition) + throw IOException("Error, readPosition out of range"); + + return doRead(rpos, data, len); +} + +size_t Buffer::writeAbsolute(StreamOffset writePosition, char const* data, size_t len) { + size_t wpos = writePosition; + if ((StreamOffset)wpos != writePosition) + throw IOException("Error, writePosition out of range"); + + return doWrite(wpos, data, len); +} + +void Buffer::open(IOMode mode) { + setMode(mode); + if (mode & IOMode::Write && mode & IOMode::Truncate) + resize(0); + if (mode & IOMode::Append) + seek(0, IOSeek::End); +} + +String Buffer::deviceName() const { + return strf("Buffer <%s>", this); +} + +StreamOffset Buffer::size() { + return m_bytes.size(); +} + +ByteArray& Buffer::data() { + return m_bytes; +} + +ByteArray const& Buffer::data() const { + return m_bytes; +} + +ByteArray Buffer::takeData() { + ByteArray ret = move(m_bytes); + reset(0); + return ret; +} + +char* Buffer::ptr() { + return data().ptr(); +} + +char const* Buffer::ptr() const { + return m_bytes.ptr(); +} + +size_t Buffer::dataSize() const { + return m_bytes.size(); +} + +void Buffer::reserve(size_t size) { + data().reserve(size); +} + +void Buffer::clear() { + m_pos = 0; + m_bytes.clear(); +} + +bool Buffer::empty() const { + return m_bytes.empty(); +} + +void Buffer::reset(size_t newSize) { + m_pos = 0; + m_bytes.fill(newSize, 0); +} + +void Buffer::reset(ByteArray b) { + m_pos = 0; + m_bytes = move(b); +} + +Buffer& Buffer::operator=(Buffer const& buffer) { + IODevice::operator=(buffer); + m_pos = buffer.m_pos; + m_bytes = buffer.m_bytes; + return *this; +} + +Buffer& Buffer::operator=(Buffer&& buffer) { + IODevice::operator=(buffer); + m_pos = buffer.m_pos; + m_bytes = move(buffer.m_bytes); + + buffer.m_pos = 0; + buffer.m_bytes = ByteArray(); + + return *this; +} + +size_t Buffer::doRead(size_t pos, char* data, size_t len) { + if (len == 0) + return 0; + + if (!isReadable()) + throw IOException("Error, read called on non-readable Buffer"); + + if (pos >= m_bytes.size()) + return 0; + + size_t l = min(m_bytes.size() - pos, len); + memcpy(data, m_bytes.ptr() + pos, l); + return l; +} + +size_t Buffer::doWrite(size_t pos, char const* data, size_t len) { + if (len == 0) + return 0; + + if (!isWritable()) + throw EofException("Error, write called on non-writable Buffer"); + + if (pos + len > m_bytes.size()) + m_bytes.resize(pos + len); + + memcpy(m_bytes.ptr() + pos, data, len); + return len; +} + +ExternalBuffer::ExternalBuffer() + : m_pos(0), m_bytes(nullptr), m_size(0) { + setMode(IOMode::Read); +} + +ExternalBuffer::ExternalBuffer(char const* externalData, size_t len) : ExternalBuffer() { + reset(externalData, len); +} + +StreamOffset ExternalBuffer::pos() { + return m_pos; +} + +void ExternalBuffer::seek(StreamOffset pos, IOSeek mode) { + StreamOffset newPos = m_pos; + if (mode == IOSeek::Absolute) + newPos = pos; + else if (mode == IOSeek::Relative) + newPos += pos; + else if (mode == IOSeek::End) + newPos = m_size - pos; + m_pos = newPos; +} + +bool ExternalBuffer::atEnd() { + return m_pos >= m_size; +} + +size_t ExternalBuffer::read(char* data, size_t len) { + size_t l = doRead(m_pos, data, len); + m_pos += l; + return l; +} + +size_t ExternalBuffer::write(char const*, size_t) { + throw IOException("Error, ExternalBuffer is not writable"); +} + +size_t ExternalBuffer::readAbsolute(StreamOffset readPosition, char* data, size_t len) { + size_t rpos = readPosition; + if ((StreamOffset)rpos != readPosition) + throw IOException("Error, readPosition out of range"); + + return doRead(rpos, data, len); +} + +size_t ExternalBuffer::writeAbsolute(StreamOffset, char const*, size_t) { + throw IOException("Error, ExternalBuffer is not writable"); +} + +String ExternalBuffer::deviceName() const { + return strf("ExternalBuffer <%s>", this); +} + +StreamOffset ExternalBuffer::size() { + return m_size; +} + +char const* ExternalBuffer::ptr() const { + return m_bytes; +} + +size_t ExternalBuffer::dataSize() const { + return m_size; +} + +bool ExternalBuffer::empty() const { + return m_size == 0; +} + +void ExternalBuffer::reset(char const* externalData, size_t len) { + m_pos = 0; + m_bytes = externalData; + m_size = len; +} + +size_t ExternalBuffer::doRead(size_t pos, char* data, size_t len) { + if (len == 0) + return 0; + + if (!isReadable()) + throw IOException("Error, read called on non-readable Buffer"); + + if (pos >= m_size) + return 0; + + size_t l = min(m_size - pos, len); + memcpy(data, m_bytes + pos, l); + return l; +} + +} -- cgit v1.2.3