diff options
Diffstat (limited to 'source/base/StarMemoryAssetSource.cpp')
-rw-r--r-- | source/base/StarMemoryAssetSource.cpp | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/source/base/StarMemoryAssetSource.cpp b/source/base/StarMemoryAssetSource.cpp new file mode 100644 index 0000000..9c777ed --- /dev/null +++ b/source/base/StarMemoryAssetSource.cpp @@ -0,0 +1,86 @@ +#include "StarMemoryAssetSource.hpp" +#include "StarDataStreamDevices.hpp" +#include "StarDataStreamExtra.hpp" +#include "StarSha256.hpp" + +namespace Star { + +MemoryAssetSource::MemoryAssetSource(JsonObject metadata) : m_metadata(metadata) {} + +JsonObject MemoryAssetSource::metadata() const { + return m_metadata; +} + +StringList MemoryAssetSource::assetPaths() const { + return m_files.keys(); +} + +IODevicePtr MemoryAssetSource::open(String const& path) { + struct AssetReader : public IODevice { + AssetReader(ByteArrayPtr assetData, String name) : assetData(assetData), name(name) { setMode(IOMode::Read); } + + size_t read(char* data, size_t len) override { + len = min<StreamOffset>(len, StreamOffset(assetData->size()) - assetPos); + assetData->copyTo(data, len); + return len; + } + + size_t write(char const*, size_t) override { + throw IOException("Assets IODevices are read-only"); + } + + StreamOffset size() override { return assetData->size(); } + StreamOffset pos() override { return assetPos; } + + String deviceName() const override { return name; } + + bool atEnd() override { + return assetPos >= assetData->size(); + } + + void seek(StreamOffset p, IOSeek mode) override { + if (mode == IOSeek::Absolute) + assetPos = p; + else if (mode == IOSeek::Relative) + assetPos = clamp<StreamOffset>(assetPos + p, 0, assetData->size()); + else + assetPos = clamp<StreamOffset>(assetPos - p, 0, assetData->size()); + } + + ByteArrayPtr assetData; + StreamOffset assetPos; + String name; + }; + + auto p = m_files.ptr(path); + if (!p) + throw AssetSourceException::format("Requested file '{}' does not exist in memory", path); + + return make_shared<AssetReader>(*p, path); +} + +bool MemoryAssetSource::empty() const { + return m_files.empty(); +} + +bool MemoryAssetSource::contains(String const& path) const { + return m_files.contains(path); +} + +bool MemoryAssetSource::erase(String const& path) { + return m_files.erase(path) != 0; +} + +bool MemoryAssetSource::set(String const& path, ByteArray data) { + return m_files.emplace(path, make_shared<ByteArray>(std::move(data))).second; +} + +ByteArray MemoryAssetSource::read(String const& path) { + auto p = m_files.ptr(path); + if (!p) + throw AssetSourceException::format("Requested file '{}' does not exist in memory", path); + else + return *p->get(); // this is a double indirection, and that freaking sucks!! +} + +} |