13
0

VST3: implement Read-Only sub-stream

This commit is contained in:
Robin Gareus 2020-10-09 20:55:41 +02:00
parent e71cc6892e
commit 5a25db34ae
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
2 changed files with 136 additions and 2 deletions

View File

@ -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)

View File

@ -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;
}