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_);
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 + (cacheEnd - fOffset_);
52 virtual optional<span<ELEMENT_TYPE>> Read (span<ELEMENT_TYPE> intoBuffer, [[maybe_unused]]
NoDataAvailableHandling blockFlag)
override
54 Require (not intoBuffer.empty ());
55 AssertExternallySynchronizedChecker::WriteContext declareContext{fThisAssertExternallySynchronized_};
59 SeekOffsetType cacheEnd = fCacheBaseOffset_ + fCachedData_.size ();
60 if (fCacheBaseOffset_ <= fOffset_ and fOffset_ < cacheEnd) [[unlikely]] {
63 size_t copyCnt = min<size_t> (
static_cast<size_t> (cacheEnd - fOffset_), intoBuffer.size ());
64 auto r = Memory::CopyBytes (span{fCachedData_}.subspan (
static_cast<size_t> (fOffset_ - fCacheBaseOffset_), copyCnt), intoBuffer);
71 Assert (fOffset_ == inherited::fRealIn.GetOffset ());
72 auto r = this->fRealIn.ReadOrThrow (intoBuffer, blockFlag);
74 fCachedData_.push_back (r);
75 fOffset_ += r.size ();
80 AssertExternallySynchronizedChecker::ReadContext declareContext{fThisAssertExternallySynchronized_};
85 static const auto kException_ = range_error{
"seek"};
86 AssertExternallySynchronizedChecker::WriteContext declareContext{fThisAssertExternallySynchronized_};
88 case Whence::eFromStart: {
89 if (offset < 0) [[unlikely]] {
90 Execution::Throw (kException_);
93 Require (newOffset >= fCacheBaseOffset_);
94 SeekOffsetType cacheEnd = fCacheBaseOffset_ + fCachedData_.size ();
95 while (newOffset > cacheEnd) {
99 auto r = this->fRealIn.ReadBlocking (span{someBuf});
100 if (r.empty ()) [[unlikely]] {
103 Execution::Throw (kException_);
105 fCachedData_.push_back (r);
106 cacheEnd = fCacheBaseOffset_ + fCachedData_.size ();
108 Assert (newOffset <= cacheEnd);
109 fOffset_ = newOffset;
113 return this->SeekRead (eFromStart, fOffset_ + offset);
116 if (
auto remainingLength = this->RemainingLength ()) {
117 return this->SeekRead (eFromStart, fOffset_ + *remainingLength + offset);
122 byte someBuf[8 * 1024];
123 auto r = this->fRealIn.ReadBlocking (span{someBuf});
124 fCachedData_.push_back (r);
129 SeekOffsetType realEnd = fCacheBaseOffset_ + fCachedData_.size ();
130 Assert (realEnd == this->fRealIn.GetOffset ());
131 return this->SeekRead (eFromStart, realEnd + offset);
146 if (in.IsSeekable ()) {