#pragma once #include "StarBuffer.hpp" #include "StarDataStream.hpp" namespace Star { // Implements DataStream using function objects as implementations of read/write. class DataStreamFunctions : public DataStream { public: // Either reader or writer can be unset, if unset then the readData/writeData // implementations will throw DataStreamException as unimplemented. DataStreamFunctions(function reader, function writer); void readData(char* data, size_t len) override; void writeData(char const* data, size_t len) override; private: function m_reader; function m_writer; }; class DataStreamIODevice : public DataStream { public: DataStreamIODevice(IODevicePtr device); IODevicePtr const& device() const; void seek(size_t pos, IOSeek seek = IOSeek::Absolute); bool atEnd(); StreamOffset pos(); void readData(char* data, size_t len) override; void writeData(char const* data, size_t len) override; private: IODevicePtr m_device; }; class DataStreamBuffer : public DataStream { public: // Convenience methods to serialize to / from ByteArray directly without // having to construct a temporary DataStreamBuffer to do it template static ByteArray serialize(T const& t); template static ByteArray serializeContainer(T const& t); template static ByteArray serializeContainer(T const& t, WriteFunction writeFunction); template static ByteArray serializeMapContainer(T const& t); template static ByteArray serializeMapContainer(T const& t, WriteFunction writeFunction); template static void deserialize(T& t, ByteArray data); template static void deserializeContainer(T& t, ByteArray data); template static void deserializeContainer(T& t, ByteArray data, ReadFunction readFunction); template static void deserializeMapContainer(T& t, ByteArray data); template static void deserializeMapContainer(T& t, ByteArray data, ReadFunction readFunction); template static T deserialize(ByteArray data); template static T deserializeContainer(ByteArray data); template static T deserializeContainer(ByteArray data, ReadFunction readFunction); template static T deserializeMapContainer(ByteArray data); template static T deserializeMapContainer(ByteArray data, ReadFunction readFunction); DataStreamBuffer(); DataStreamBuffer(size_t initialSize); DataStreamBuffer(ByteArray b); // Resize existing buffer to new size. void resize(size_t size); void reserve(size_t size); void clear(); ByteArray& data(); ByteArray const& data() const; ByteArray takeData(); char* ptr(); char const* ptr() const; BufferPtr const& device() const; size_t size() const; bool empty() const; void seek(size_t pos, IOSeek seek = IOSeek::Absolute); bool atEnd(); size_t pos(); // Set new buffer. void reset(size_t newSize); void reset(ByteArray b); void readData(char* data, size_t len) override; void writeData(char const* data, size_t len) override; private: BufferPtr m_buffer; }; class DataStreamExternalBuffer : public DataStream { public: DataStreamExternalBuffer(); explicit DataStreamExternalBuffer(ByteArray const& byteArray); explicit DataStreamExternalBuffer(DataStreamBuffer const& buffer); DataStreamExternalBuffer(DataStreamExternalBuffer const& buffer) = default; DataStreamExternalBuffer(char const* externalData, size_t len); char const* ptr() const; size_t size() const; bool empty() const; void seek(size_t pos, IOSeek mode = IOSeek::Absolute); bool atEnd(); size_t pos(); size_t remaining(); void reset(char const* externalData, size_t len); void readData(char* data, size_t len) override; void writeData(char const* data, size_t len) override; private: ExternalBuffer m_buffer; }; template ByteArray DataStreamBuffer::serialize(T const& t) { DataStreamBuffer ds; ds.write(t); return ds.takeData(); } template ByteArray DataStreamBuffer::serializeContainer(T const& t) { DataStreamBuffer ds; ds.writeContainer(t); return ds.takeData(); } template ByteArray DataStreamBuffer::serializeContainer(T const& t, WriteFunction writeFunction) { DataStreamBuffer ds; ds.writeContainer(t, writeFunction); return ds.takeData(); } template ByteArray DataStreamBuffer::serializeMapContainer(T const& t) { DataStreamBuffer ds; ds.writeMapContainer(t); return ds.takeData(); } template ByteArray DataStreamBuffer::serializeMapContainer(T const& t, WriteFunction writeFunction) { DataStreamBuffer ds; ds.writeMapContainer(t, writeFunction); return ds.takeData(); } template void DataStreamBuffer::deserialize(T& t, ByteArray data) { DataStreamBuffer ds(std::move(data)); ds.read(t); } template void DataStreamBuffer::deserializeContainer(T& t, ByteArray data) { DataStreamBuffer ds(std::move(data)); ds.readContainer(t); } template void DataStreamBuffer::deserializeContainer(T& t, ByteArray data, ReadFunction readFunction) { DataStreamBuffer ds(std::move(data)); ds.readContainer(t, readFunction); } template void DataStreamBuffer::deserializeMapContainer(T& t, ByteArray data) { DataStreamBuffer ds(std::move(data)); ds.readMapContainer(t); } template void DataStreamBuffer::deserializeMapContainer(T& t, ByteArray data, ReadFunction readFunction) { DataStreamBuffer ds(std::move(data)); ds.readMapContainer(t, readFunction); } template T DataStreamBuffer::deserialize(ByteArray data) { T t; deserialize(t, std::move(data)); return t; } template T DataStreamBuffer::deserializeContainer(ByteArray data) { T t; deserializeContainer(t, std::move(data)); return t; } template T DataStreamBuffer::deserializeContainer(ByteArray data, ReadFunction readFunction) { T t; deserializeContainer(t, std::move(data), readFunction); return t; } template T DataStreamBuffer::deserializeMapContainer(ByteArray data) { T t; deserializeMapContainer(t, std::move(data)); return t; } template T DataStreamBuffer::deserializeMapContainer(ByteArray data, ReadFunction readFunction) { T t; deserializeMapContainer(t, std::move(data), readFunction); return t; } }