25 , fCacheBaseOffset_{fOffset_}
27 Assert (not this->fRealIn.IsSeekable ());
29 virtual bool IsSeekable ()
const override
33 virtual optional<size_t> AvailableToRead ()
override
35 SeekOffsetType cacheEnd = fCacheBaseOffset_ + fCachedData_.size ();
36 if (fCacheBaseOffset_ <= fOffset_ and fOffset_ < cacheEnd) [[unlikely]] {
37 Ensure (cacheEnd - fOffset_ > 0);
38 return static_cast<size_t> (cacheEnd - fOffset_);
40 return this->fRealIn.AvailableToRead ();
42 virtual optional<SeekOffsetType> RemainingLength ()
override
44 auto baseRemaining = this->fRealIn.RemainingLength ();
46 SeekOffsetType cacheEnd = fCacheBaseOffset_ + fCachedData_.size ();
47 Assert (fOffset_ <= cacheEnd);
48 baseRemaining = *baseRemaining +
static_cast<size_t> (cacheEnd - fOffset_);
52 virtual optional<span<ELEMENT_TYPE>> Read (span<ELEMENT_TYPE> intoBuffer, [[maybe_unused]]
NoDataAvailableHandling blockFlag)
override
54 Require (not intoBuffer.empty ());
55 AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
59 SeekOffsetType cacheEnd = fCacheBaseOffset_ + fCachedData_.size ();
60 if (fCacheBaseOffset_ <= fOffset_ and fOffset_ < cacheEnd) [[unlikely]] {
61 size_t copyCnt = max<size_t> (
static_cast<size_t> (cacheEnd - fOffset_), intoBuffer.size ());
62 auto r = Memory::CopyBytes (span{fCachedData_}.subspan (
static_cast<size_t> (fOffset_ - fCacheBaseOffset_), copyCnt), intoBuffer);
69 Assert (fOffset_ == inherited::fRealIn.GetOffset ());
70 auto r = this->fRealIn.ReadOrThrow (intoBuffer, blockFlag);
72 fCachedData_.push_back (r);
73 fOffset_ += r.size ();
78 AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
83 static const auto kException_ = range_error{
"seek"};
84 AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
86 case Whence::eFromStart: {
87 if (offset < 0) [[unlikely]] {
88 Execution::Throw (kException_);
91 Require (newOffset >= fCacheBaseOffset_);
92 SeekOffsetType cacheEnd = fCacheBaseOffset_ + fCachedData_.size ();
93 while (newOffset > cacheEnd) {
97 auto r = this->fRealIn.ReadBlocking (span{someBuf});
98 fCachedData_.push_back (r);
99 cacheEnd = fCacheBaseOffset_ + fCachedData_.size ();
101 Assert (newOffset <= cacheEnd);
102 fOffset_ = newOffset;
106 return this->SeekRead (eFromStart, fOffset_ + offset);
109 if (
auto remainingLength = this->RemainingLength ()) {
110 return this->SeekRead (eFromStart, fOffset_ + *remainingLength + offset);
115 byte someBuf[8 * 1024];
116 auto r = this->fRealIn.ReadBlocking (span{someBuf});
117 fCachedData_.push_back (r);
122 SeekOffsetType realEnd = fCacheBaseOffset_ + fCachedData_.size ();
123 Assert (realEnd == this->fRealIn.GetOffset ());
124 return this->SeekRead (eFromStart, realEnd + offset);
139 if (in.IsSeekable ()) {