PluginManager: Refactor to make use of new API

* General refactor, moved BDataIO emulation in a
BAdapterIO derived class, BDataIOAdapter.
* This allowed to simplify the wrapper that is now
considering everything to be seekable or pseudo-seekable.
This commit is contained in:
Dario Casalinuovo
2016-05-31 01:15:09 +02:00
parent b660d95f88
commit 0a2584e464
+98 -87
View File
@@ -1,11 +1,13 @@
/* /*
* Copyright 2004-2010, Marcus Overhagen. All rights reserved. * Copyright 2004-2010, Marcus Overhagen. All rights reserved.
* Copyright 2016, Dario Casalinuovo. All rights reserved.
* Distributed under the terms of the OpenBeOS License. * Distributed under the terms of the OpenBeOS License.
*/ */
#include <AdapterIO.h>
#include <BufferIO.h> #include <BufferIO.h>
#include <DataIO.h> #include <DataIO.h>
#include <File.h>
#include <image.h> #include <image.h>
#include <Path.h> #include <Path.h>
@@ -23,30 +25,84 @@ PluginManager gPluginManager;
#define MAX_STREAMERS 40 #define MAX_STREAMERS 40
class BMediaIOWrapper : public BMediaIO { class DataIOAdapter : public BAdapterIO
{
public:
DataIOAdapter(BDataIO* dataIO)
:
BAdapterIO(B_MEDIA_SEEK_BACKWARD | B_MEDIA_MUTABLE_SIZE,
B_INFINITE_TIMEOUT),
fDataIO(dataIO)
{
fDataInputAdapter = BuildInputAdapter();
}
virtual ~DataIOAdapter()
{
}
virtual ssize_t ReadAt(off_t position, void* buffer,
size_t size)
{
if (position == Position()) {
ssize_t ret = fDataIO->Read(buffer, size);
fDataInputAdapter->Write(buffer, ret);
return ret;
}
off_t totalSize = 0;
if (GetSize(&totalSize) != B_OK)
return B_UNSUPPORTED;
if (position+size < totalSize)
return ReadAt(position, buffer, size);
return B_NOT_SUPPORTED;
}
virtual ssize_t WriteAt(off_t position, const void* buffer,
size_t size)
{
if (position == Position()) {
ssize_t ret = fDataIO->Write(buffer, size);
fDataInputAdapter->Write(buffer, ret);
return ret;
}
return B_NOT_SUPPORTED;
}
private:
BDataIO* fDataIO;
BInputAdapter* fDataInputAdapter;
};
class BMediaIOWrapper : public BMediaIO
{
public: public:
BMediaIOWrapper(BDataIO* source) BMediaIOWrapper(BDataIO* source)
: :
fData(NULL), fData(NULL),
fPosition(NULL), fPosition(NULL),
fMedia(NULL), fMedia(NULL),
fFile(NULL), fBufferIO(NULL),
fFallbackBuffer(NULL), fDataIOAdapter(NULL),
fErr(B_NO_ERROR) fErr(B_NO_ERROR)
{ {
CALLED(); CALLED();
fPosition = dynamic_cast<BPositionIO*>(source); fPosition = dynamic_cast<BPositionIO*>(source);
fMedia = dynamic_cast<BMediaIO*>(source); fMedia = dynamic_cast<BMediaIO*>(source);
fFile = dynamic_cast<BFile*>(source); fBufferIO = dynamic_cast<BBufferIO *>(source);
fData = source; fData = source;
// No need to do additional buffering if we have // No need to do additional buffering if we have
// a BBufferIO or a BMediaIO. // a BBufferIO or a BMediaIO.
if (dynamic_cast<BBufferIO *>(source) == NULL) { if (!IsMedia() && fBufferIO == NULL) {
// Source needs to be at least a BPositionIO to wrap with a BBufferIO // Source needs to be at least a BPositionIO to wrap with a BBufferIO
if (IsSeekable()) { if (IsPosition()) {
fPosition = new(std::nothrow) BBufferIO(fPosition, 65536, true); fPosition = new(std::nothrow) BBufferIO(fPosition, 65536, false);
if (fPosition == NULL) { if (fPosition == NULL) {
fErr = B_NO_MEMORY; fErr = B_NO_MEMORY;
return; return;
@@ -57,17 +113,34 @@ public:
// In this case we have to supply our own form // In this case we have to supply our own form
// of pseudo-seekable object from a non-seekable // of pseudo-seekable object from a non-seekable
// BDataIO. // BDataIO.
fFallbackBuffer = new BMallocIO(); fDataIOAdapter = new DataIOAdapter(source);
fFallbackBuffer->SetBlockSize(BLOCK_SIZE); fMedia = dynamic_cast<BMediaIO*>(fDataIOAdapter);
fPosition = dynamic_cast<BPositionIO*>(fDataIOAdapter);
fData = dynamic_cast<BDataIO*>(fDataIOAdapter);
TRACE("Unable to improve performance with a BufferIO\n"); TRACE("Unable to improve performance with a BufferIO\n");
} }
} }
if (IsMedia())
fMedia->GetFlags(&fFlags);
else if (IsPosition())
fFlags = B_MEDIA_SEEKABLE;
} }
virtual ~BMediaIOWrapper() virtual ~BMediaIOWrapper()
{ {
delete fData; if (fBufferIO != NULL)
delete fFallbackBuffer; delete fBufferIO;
if (fDataIOAdapter != NULL)
delete fDataIOAdapter;
}
// BMediaIO interface
virtual void GetFlags(int32* flags) const
{
*flags = fFlags;
} }
// BPositionIO interface // BPositionIO interface
@@ -77,28 +150,7 @@ public:
{ {
CALLED(); CALLED();
if (IsSeekable()) return fPosition->ReadAt(position, buffer, size);
return fPosition->ReadAt(position, buffer, size);
off_t bufSize = 0;
ssize_t ret = B_NOT_SUPPORTED;
fFallbackBuffer->GetSize(&bufSize);
if (fFallbackBuffer->Position() == position
&& position+size > (size_t)bufSize) {
// TODO: Possibly part of the data we have
// to supply is cached.
ret = fData->Read(buffer, size);
if (ret > 0)
fFallbackBuffer->Write(buffer, ret);
return ret;
}
if (position+size <= (size_t)bufSize)
return fFallbackBuffer->ReadAt(position, buffer, size);
return ret;
} }
virtual ssize_t WriteAt(off_t position, const void* buffer, virtual ssize_t WriteAt(off_t position, const void* buffer,
@@ -106,52 +158,28 @@ public:
{ {
CALLED(); CALLED();
if (IsSeekable()) return fPosition->WriteAt(position, buffer, size);
return fPosition->WriteAt(position, buffer, size);
off_t bufSize = 0;
fFallbackBuffer->GetSize(&bufSize);
if (position == bufSize) {
ssize_t ret = fData->Write(buffer, size);
fFallbackBuffer->WriteAt(bufSize, buffer, size);
return ret;
}
return B_NOT_SUPPORTED;
} }
virtual off_t Seek(off_t position, uint32 seekMode) virtual off_t Seek(off_t position, uint32 seekMode)
{ {
CALLED(); CALLED();
if (IsSeekable()) return fPosition->Seek(position, seekMode);
return fPosition->Seek(position, seekMode);
off_t bufSize = 0;
fFallbackBuffer->GetSize(&bufSize);
if (position <= bufSize)
return fFallbackBuffer->Seek(position, seekMode);
return B_NOT_SUPPORTED;
} }
virtual off_t Position() const virtual off_t Position() const
{ {
CALLED(); CALLED();
if (IsSeekable()) return fPosition->Position();
return fPosition->Position();
return fFallbackBuffer->Position();
} }
virtual status_t SetSize(off_t size) virtual status_t SetSize(off_t size)
{ {
CALLED(); CALLED();
if (IsEndless())
return B_NOT_SUPPORTED;
return fPosition->SetSize(size); return fPosition->SetSize(size);
} }
@@ -159,33 +187,9 @@ public:
{ {
CALLED(); CALLED();
if (IsEndless())
return B_NOT_SUPPORTED;
return fPosition->GetSize(size); return fPosition->GetSize(size);
} }
// BMediaIO interface
virtual bool IsSeekable() const
{
if (IsMedia())
return fMedia->IsSeekable();
return fPosition != NULL;
}
virtual bool IsEndless() const
{
if (IsMedia())
return fMedia->IsEndless();
if (IsSeekable())
return false;
return true;
}
// Utility methods // Utility methods
status_t InitCheck() const status_t InitCheck() const
@@ -200,13 +204,20 @@ protected:
return fMedia != NULL; return fMedia != NULL;
} }
bool IsPosition() const
{
return fPosition != NULL;
}
private: private:
BDataIO* fData; BDataIO* fData;
BPositionIO* fPosition; BPositionIO* fPosition;
BMediaIO* fMedia; BMediaIO* fMedia;
BFile* fFile; BBufferIO* fBufferIO;
DataIOAdapter* fDataIOAdapter;
int32 fFlags;
BMallocIO* fFallbackBuffer;
status_t fErr; status_t fErr;
}; };