From 5a25db34ae3b3d2557b479cfde415ce168d542ad Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 9 Oct 2020 20:55:41 +0200 Subject: [PATCH] VST3: implement Read-Only sub-stream --- libs/ardour/ardour/vst3_host.h | 28 ++++++++- libs/ardour/vst3_host.cc | 110 +++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 2 deletions(-) diff --git a/libs/ardour/ardour/vst3_host.h b/libs/ardour/ardour/vst3_host.h index 5ccb53d9f3..af8e18b75b 100644 --- a/libs/ardour/ardour/vst3_host.h +++ b/libs/ardour/ardour/vst3_host.h @@ -146,8 +146,8 @@ class LIBARDOUR_API RefObject : public FUnknown public: RefObject (); virtual ~RefObject () {} - uint32 PLUGIN_API addRef (); - uint32 PLUGIN_API release (); + uint32 PLUGIN_API addRef () SMTG_OVERRIDE; + uint32 PLUGIN_API release () SMTG_OVERRIDE; private: gint _cnt; // atomic @@ -416,6 +416,30 @@ private: HostAttributeList attribute_list; }; +class LIBARDOUR_LOCAL ROMStream : public IBStream +{ +public: + ROMStream (IBStream& src, TSize offset, TSize size); + virtual ~ROMStream (); + + tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) SMTG_OVERRIDE; + uint32 PLUGIN_API addRef () SMTG_OVERRIDE { return 1; } + uint32 PLUGIN_API release () SMTG_OVERRIDE { return 1; } + + /* IBStream API */ + tresult PLUGIN_API read (void* buffer, int32 numBytes, int32* numBytesRead) SMTG_OVERRIDE; + tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten) SMTG_OVERRIDE; + tresult PLUGIN_API seek (int64 pos, int32 mode, int64* result) SMTG_OVERRIDE; + tresult PLUGIN_API tell (int64* pos) SMTG_OVERRIDE; + +protected: + IBStream& _stream; + int64 _offset; + int64 _size; + int64 _pos; +}; + + #if defined(__clang__) # pragma clang diagnostic pop #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) diff --git a/libs/ardour/vst3_host.cc b/libs/ardour/vst3_host.cc index fb1783be24..d779d066e0 100644 --- a/libs/ardour/vst3_host.cc +++ b/libs/ardour/vst3_host.cc @@ -608,6 +608,9 @@ RAMStream::read (void* buffer, int32 n_bytes, int32* n_read) tresult RAMStream::write (void* buffer, int32 n_bytes, int32* n_written) { + if (n_written) { + *n_written = 0; + } if (_readonly) { return kResultFalse; } @@ -853,3 +856,110 @@ RAMStream::hexdump (int64 max_len) const std::cout << out.str (); } #endif + +ROMStream::ROMStream (IBStream& src, TSize offset, TSize size) + : _stream (src) + , _offset (offset) + , _size (size) +{ + _stream.addRef (); +} + +ROMStream::~ROMStream () +{ + _stream.release (); +} + +tresult +ROMStream::queryInterface (const TUID _iid, void** obj) +{ + QUERY_INTERFACE (_iid, obj, FUnknown::iid, IBStream) + QUERY_INTERFACE (_iid, obj, IBStream::iid, IBStream) + + *obj = nullptr; + return kNoInterface; +} + +tresult +ROMStream::read (void* buffer, int32 n_bytes, int32* n_read) +{ + int64 available = _size - _pos; + + if (n_read) { + *n_read = 0; + } + + if (n_bytes < 0 || available < 0) { + n_bytes = 0; + return kResultOk; + } + + if (n_bytes > available) { + n_bytes = available; + } + + tresult result = _stream.seek (_offset + _pos, kIBSeekSet); + if (result != kResultOk) { + return result; + } + + int32 _n_read = 0; + result = _stream.read (buffer, n_bytes, &_n_read); + + if (_n_read > 0) { + _pos += _n_read; + } + if (n_read) { + *n_read = _n_read; + } + + return result; +} + +tresult +ROMStream::write (void* buffer, int32 n_bytes, int32* n_written) +{ + if (n_written) { + *n_written = 0; + } + return kNotImplemented; +} + +tresult +ROMStream::seek (int64 pos, int32 mode, int64* result) +{ + switch (mode) { + case kIBSeekSet: + _pos = pos; + break; + case kIBSeekCur: + _pos += pos; + break; + case kIBSeekEnd: + _pos = _size + pos; + break; + default: + return kInvalidArgument; + } + if (_pos < 0) { + _pos = 0; + } + if (_pos > _size) { + _pos = _size; + } + + if (result) { + *result = _pos; + } + return kResultTrue; +} + +tresult +ROMStream::tell (int64* pos) +{ + if (!pos) { + return kInvalidArgument; + } + *pos = _pos; + return kResultTrue; +}