24 , fSrcIter_{fSource_.
begin ()}
32 virtual bool IsSeekable ()
const override
36 virtual void CloseRead ()
override
39 Ensure (not IsOpenRead ());
41 virtual bool IsOpenRead ()
const override
45 virtual optional<size_t> AvailableToRead ()
override
47 Require (IsOpenRead ());
48 AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
50 return fSrcIter_.Done () ? 0 : 1;
52 virtual optional<SeekOffsetType> RemainingLength ()
override
54 AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
55 Require (IsOpenRead ());
59 virtual optional<span<ELEMENT_TYPE>> Read (span<ELEMENT_TYPE> intoBuffer, [[maybe_unused]]
NoDataAvailableHandling blockFlag)
override
61 Require (not intoBuffer.empty ());
62 AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
63 Require (IsOpenRead ());
64 ELEMENT_TYPE* outI = intoBuffer.data ();
71 for (; fSrcIter_ != fSource_.end () and outI != intoBuffer.data () + intoBuffer.size (); ++fSrcIter_, ++outI) {
75 if (outI > intoBuffer.data ()) {
76 fPrevCharCached_ = *(outI - 1);
79 fPrevCharCached_ = nullopt;
81 return intoBuffer.subspan (0, outI - intoBuffer.data ());
85 AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
86 Require (IsOpenRead ());
88 Assert (fOffset_ >= 1);
95 Require (IsOpenRead ());
96 static const auto kException_ = range_error{
"seek"};
97 AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
98 size_t sourceLen = fSource_.size ();
102 if (offset < 0) [[unlikely]] {
103 Execution::Throw (kException_);
105 if (
static_cast<SeekOffsetType> (offset) > sourceLen) [[unlikely]] {
106 Execution::Throw (kException_);
112 if (tmpOffset < 0) [[unlikely]] {
113 Execution::Throw (kException_);
115 if (
static_cast<SeekOffsetType> (tmpOffset) > sourceLen) [[unlikely]] {
116 Execution::Throw (kException_);
122 if (tmpOffset < 0) [[unlikely]] {
123 Execution::Throw (kException_);
125 if (
static_cast<SeekOffsetType> (tmpOffset) > sourceLen) [[unlikely]] {
126 Execution::Throw (kException_);
131 if (newOffset == fOffset_ - 1 and fPrevCharCached_) {
132 fPutBack_ = fPrevCharCached_;
133 fPrevCharCached_ = nullopt;
134 return GetReadOffset ();
136 else if (newOffset < fOffset_) {
137 fSrcIter_ = fSource_.begin ();
140 while (fOffset_ < newOffset) {
141 if (fSrcIter_.Done ()) {
152 Iterable<ELEMENT_TYPE> fSource_;
153 Iterator<ELEMENT_TYPE> fSrcIter_;
155 optional<ELEMENT_TYPE> fPrevCharCached_{};
156 optional<ELEMENT_TYPE> fPutBack_{};