25 , fSrcIter_{fSource_.
begin ()}
33 virtual bool IsSeekable ()
const override
37 virtual void CloseRead ()
override
40 Ensure (not IsOpenRead ());
42 virtual bool IsOpenRead ()
const override
46 virtual optional<size_t> AvailableToRead ()
override
48 Require (IsOpenRead ());
49 AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
51 return fSrcIter_.Done () ? 0 : 1;
53 virtual optional<SeekOffsetType> RemainingLength ()
override
55 AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
56 Require (IsOpenRead ());
60 virtual optional<span<ELEMENT_TYPE>> Read (span<ELEMENT_TYPE> intoBuffer, [[maybe_unused]]
NoDataAvailableHandling blockFlag)
override
62 Require (not intoBuffer.empty ());
63 AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
64 Require (IsOpenRead ());
65 ELEMENT_TYPE* outI = intoBuffer.data ();
72 for (; fSrcIter_ != fSource_.end () and outI != intoBuffer.data () + intoBuffer.size (); ++fSrcIter_, ++outI) {
76 if (outI > intoBuffer.data ()) {
77 fPrevCharCached_ = *(outI - 1);
80 fPrevCharCached_ = nullopt;
82 return intoBuffer.subspan (0, outI - intoBuffer.data ());
86 AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
87 Require (IsOpenRead ());
89 Assert (fOffset_ >= 1);
96 Require (IsOpenRead ());
97 static const auto kException_ = range_error{
"seek"};
98 AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
99 size_t sourceLen = fSource_.size ();
103 if (offset < 0) [[unlikely]] {
104 Execution::Throw (kException_);
106 if (
static_cast<SeekOffsetType> (offset) > sourceLen) [[unlikely]] {
107 Execution::Throw (kException_);
113 if (tmpOffset < 0) [[unlikely]] {
114 Execution::Throw (kException_);
116 if (
static_cast<SeekOffsetType> (tmpOffset) > sourceLen) [[unlikely]] {
117 Execution::Throw (kException_);
123 if (tmpOffset < 0) [[unlikely]] {
124 Execution::Throw (kException_);
126 if (
static_cast<SeekOffsetType> (tmpOffset) > sourceLen) [[unlikely]] {
127 Execution::Throw (kException_);
132 if (newOffset == fOffset_ - 1 and fPrevCharCached_) {
133 fPutBack_ = fPrevCharCached_;
134 fPrevCharCached_ = nullopt;
135 return GetReadOffset ();
137 else if (newOffset < fOffset_) {
138 fSrcIter_ = fSource_.begin ();
141 while (fOffset_ < newOffset) {
142 if (fSrcIter_.Done ()) {
153 Iterable<ELEMENT_TYPE> fSource_;
154 Iterator<ELEMENT_TYPE> fSrcIter_;
156 optional<ELEMENT_TYPE> fPrevCharCached_{};
157 optional<ELEMENT_TYPE> fPutBack_{};