24 , fCacheBaseOffset_{fOffset_}
26 Assert (not this->fRealIn.IsSeekable ());
28 virtual bool IsSeekable ()
const override
32 virtual optional<size_t> AvailableToRead ()
override
34 SeekOffsetType cacheEnd = fCacheBaseOffset_ + fCachedData_.size ();
35 if (fCacheBaseOffset_ <= fOffset_ and fOffset_ < cacheEnd) [[unlikely]] {
36 Ensure (cacheEnd - fOffset_ > 0);
37 return static_cast<size_t> (cacheEnd - fOffset_);
39 return this->fRealIn.AvailableToRead ();
41 virtual optional<SeekOffsetType> RemainingLength ()
override
43 auto baseRemaining = this->fRealIn.RemainingLength ();
45 SeekOffsetType cacheEnd = fCacheBaseOffset_ + fCachedData_.size ();
46 Assert (fOffset_ <= cacheEnd);
47 baseRemaining = *baseRemaining +
static_cast<size_t> (cacheEnd - fOffset_);
51 virtual optional<span<ELEMENT_TYPE>> Read (span<ELEMENT_TYPE> intoBuffer, [[maybe_unused]]
NoDataAvailableHandling blockFlag)
override
53 Require (not intoBuffer.empty ());
54 AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
58 SeekOffsetType cacheEnd = fCacheBaseOffset_ + fCachedData_.size ();
59 if (fCacheBaseOffset_ <= fOffset_ and fOffset_ < cacheEnd) [[unlikely]] {
60 size_t copyCnt = max<size_t> (
static_cast<size_t> (cacheEnd - fOffset_), intoBuffer.size ());
61 auto r = Memory::CopyBytes (span{fCachedData_}.subspan (
static_cast<size_t> (fOffset_ - fCacheBaseOffset_), copyCnt), intoBuffer);
68 Assert (fOffset_ == inherited::fRealIn.GetOffset ());
69 auto r = this->fRealIn.ReadOrThrow (intoBuffer, blockFlag);
71 fCachedData_.push_back (r);
72 fOffset_ += r.size ();
77 AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
82 static const auto kException_ = range_error{
"seek"};
83 AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
85 case Whence::eFromStart: {
86 if (offset < 0) [[unlikely]] {
87 Execution::Throw (kException_);
90 Require (newOffset >= fCacheBaseOffset_);
91 SeekOffsetType cacheEnd = fCacheBaseOffset_ + fCachedData_.size ();
92 while (newOffset > cacheEnd) {
96 auto r = this->fRealIn.ReadBlocking (span{someBuf});
97 fCachedData_.push_back (r);
98 cacheEnd = fCacheBaseOffset_ + fCachedData_.size ();
100 Assert (newOffset <= cacheEnd);
101 fOffset_ = newOffset;
105 return this->SeekRead (eFromStart, fOffset_ + offset);
108 if (
auto remainingLength = this->RemainingLength ()) {
109 return this->SeekRead (eFromStart, fOffset_ + *remainingLength + offset);
114 byte someBuf[8 * 1024];
115 auto r = this->fRealIn.ReadBlocking (span{someBuf});
116 fCachedData_.push_back (r);
121 SeekOffsetType realEnd = fCacheBaseOffset_ + fCachedData_.size ();
122 Assert (realEnd == this->fRealIn.GetOffset ());
123 return this->SeekRead (eFromStart, realEnd + offset);
138 if (in.IsSeekable ()) {