2 * Copyright 2016 Dario Casalinuovo. All rights reserved.
3 * Distributed under the terms of the MIT License.
16 #define TIMEOUT_QUANTA 100000
19 class RelativePositionIO
: public BPositionIO
{
21 RelativePositionIO(BAdapterIO
* owner
, BPositionIO
* buffer
,
33 virtual ~RelativePositionIO()
38 status_t
ResetStartOffset(off_t offset
)
40 status_t ret
= fBuffer
->SetSize(0);
45 fStartOffset
= offset
;
49 status_t
EvaluatePosition(off_t position
, off_t totalSize
)
54 if (position
< fStartOffset
)
55 return B_RESOURCE_UNAVAILABLE
;
57 if (totalSize
> 0 && position
> totalSize
) {
58 // This is an endless stream, we don't know
59 // how much data will come and when, we could
70 status_t
WaitForData(off_t position
, off_t size
)
73 status_t ret
= GetSize(&bufferSize
);
77 bigtime_t totalTimeOut
= 0;
79 while (bufferSize
< position
+ size
) {
80 // We are not running, no luck to receive
81 // more data, let's return and avoid locking.
82 if (!fOwner
->IsRunning())
83 return B_NOT_SUPPORTED
;
85 if (fTimeout
!= B_INFINITE_TIMEOUT
&& totalTimeOut
>= fTimeout
)
88 snooze(TIMEOUT_QUANTA
);
90 totalTimeOut
+= TIMEOUT_QUANTA
;
96 virtual ssize_t
ReadAt(off_t position
, void* buffer
,
99 AutoReadLocker
_(fLock
);
101 return fBuffer
->ReadAt(
102 _PositionToRelative(position
), buffer
, size
);
106 virtual ssize_t
WriteAt(off_t position
,
107 const void* buffer
, size_t size
)
109 AutoWriteLocker
_(fLock
);
111 return fBuffer
->WriteAt(
112 _PositionToRelative(position
), buffer
, size
);
115 virtual off_t
Seek(off_t position
, uint32 seekMode
)
117 AutoWriteLocker
_(fLock
);
119 return fBuffer
->Seek(_PositionToRelative(position
), seekMode
);
122 virtual off_t
Position() const
124 AutoReadLocker
_(fLock
);
126 return _RelativeToPosition(fBuffer
->Position());
129 virtual status_t
SetSize(off_t size
)
131 AutoWriteLocker
_(fLock
);
133 return fBuffer
->SetSize(_PositionToRelative(size
));
136 virtual status_t
GetSize(off_t
* size
) const
138 AutoReadLocker
_(fLock
);
140 // We use the backend position to make our buffer
141 // independant of that.
142 *size
= _RelativeToPosition(fBackPosition
);
147 ssize_t
BackWrite(const void* buffer
, size_t size
)
149 AutoWriteLocker
_(fLock
);
151 off_t ret
= fBuffer
->WriteAt(fBackPosition
, buffer
, size
);
152 fBackPosition
+= ret
;
156 void SetBuffer(BPositionIO
* buffer
)
162 bool IsStreaming() const
165 fOwner
->GetFlags(&flags
);
166 return (flags
& B_MEDIA_STREAMING
) == true;
169 bool IsMutable() const
172 fOwner
->GetFlags(&flags
);
173 return (flags
& B_MEDIA_MUTABLE_SIZE
) == true;
176 bool IsSeekable() const
179 fOwner
->GetFlags(&flags
);
180 return (flags
& B_MEDIA_SEEKABLE
) == true;
185 off_t
_PositionToRelative(off_t position
) const
187 return position
- fStartOffset
;
190 off_t
_RelativeToPosition(off_t position
) const
192 return position
+ fStartOffset
;
199 BPositionIO
* fBuffer
;
201 mutable RWLocker fLock
;
207 BAdapterIO::BAdapterIO(int32 flags
, bigtime_t timeout
)
218 fBuffer
= new RelativePositionIO(this, new BMallocIO(), timeout
);
222 BAdapterIO::BAdapterIO(const BAdapterIO
&)
224 // copying not allowed...
228 BAdapterIO::~BAdapterIO()
232 delete fInputAdapter
;
238 BAdapterIO::GetFlags(int32
* flags
) const
247 BAdapterIO::ReadAt(off_t position
, void* buffer
, size_t size
)
251 status_t ret
= _EvaluateWait(position
, size
);
255 return fBuffer
->ReadAt(position
, buffer
, size
);
260 BAdapterIO::WriteAt(off_t position
, const void* buffer
, size_t size
)
264 return fBuffer
->WriteAt(position
, buffer
, size
);
269 BAdapterIO::Seek(off_t position
, uint32 seekMode
)
273 off_t absolutePosition
= 0;
276 if (seekMode
== SEEK_CUR
)
277 absolutePosition
= Position()+position
;
278 else if (seekMode
== SEEK_END
) {
279 if (GetSize(&size
) != B_OK
)
280 return B_NOT_SUPPORTED
;
282 absolutePosition
= size
-position
;
285 status_t ret
= _EvaluateWait(absolutePosition
, 0);
287 if (ret
== B_RESOURCE_UNAVAILABLE
&& fBuffer
->IsStreaming()
288 && fBuffer
->IsSeekable()) {
290 fSeekSem
= create_sem(0, "BAdapterIO seek sem");
292 if (SeekRequested(absolutePosition
) != B_OK
)
293 return B_NOT_SUPPORTED
;
295 TRACE("BAdapterIO::Seek: Locking on backend seek\n");
296 acquire_sem(fSeekSem
);
297 TRACE("BAdapterIO::Seek: Seek completed!\n");
298 fBuffer
->ResetStartOffset(absolutePosition
);
299 } else if (ret
!= B_OK
)
300 return B_NOT_SUPPORTED
;
302 return fBuffer
->Seek(position
, seekMode
);
307 BAdapterIO::Position() const
311 return fBuffer
->Position();
316 BAdapterIO::SetSize(off_t size
)
320 if (!fBuffer
->IsMutable()) {
325 return fBuffer
->SetSize(size
);
330 BAdapterIO::GetSize(off_t
* size
) const
334 if (!fBuffer
->IsMutable()) {
339 return fBuffer
->GetSize(size
);
354 BAdapterIO::IsRunning() const
361 BAdapterIO::SeekCompleted()
364 release_sem(fSeekSem
);
365 delete_sem(fSeekSem
);
371 BAdapterIO::SetBuffer(BPositionIO
* buffer
)
373 // We can't change the buffer while we
378 fBuffer
->SetBuffer(buffer
);
384 BAdapterIO::BuildInputAdapter()
386 if (fInputAdapter
!= NULL
)
387 return fInputAdapter
;
389 fInputAdapter
= new BInputAdapter(this);
390 return fInputAdapter
;
395 BAdapterIO::SeekRequested(off_t position
)
404 BAdapterIO::BackWrite(const void* buffer
, size_t size
)
406 return fBuffer
->BackWrite(buffer
, size
);
411 BAdapterIO::_EvaluateWait(off_t pos
, off_t size
)
416 if (GetSize(&totalSize
) != B_OK
)
417 TRACE("BAdapterIO::ReadAt: Can't get our size!\n");
419 TRACE("BAdapterIO::_EvaluateWait TS %" B_PRId64
" P %" B_PRId64
420 " S %" B_PRId64
"\n", totalSize
, pos
, size
);
422 status_t err
= fBuffer
->EvaluatePosition(pos
, totalSize
);
424 TRACE("BAdapterIO::_EvaluateWait: %s\n", strerror(err
));
426 if (err
!= B_OK
&& err
!= B_WOULD_BLOCK
)
429 TRACE("BAdapterIO::_EvaluateWait: waiting for data\n");
431 return fBuffer
->WaitForData(pos
, size
);
435 BInputAdapter::BInputAdapter(BAdapterIO
* io
)
442 BInputAdapter::~BInputAdapter()
448 BInputAdapter::Write(const void* buffer
, size_t size
)
450 return fIO
->BackWrite(buffer
, size
);
455 void BAdapterIO::_ReservedAdapterIO1() {}
456 void BAdapterIO::_ReservedAdapterIO2() {}
457 void BAdapterIO::_ReservedAdapterIO3() {}
458 void BAdapterIO::_ReservedAdapterIO4() {}
459 void BAdapterIO::_ReservedAdapterIO5() {}
461 void BInputAdapter::_ReservedInputAdapter1() {}
462 void BInputAdapter::_ReservedInputAdapter2() {}