Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarBuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/core/StarBuffer.cpp')
-rw-r--r--source/core/StarBuffer.cpp287
1 files changed, 287 insertions, 0 deletions
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;
+}
+
+}