4#include "Stroika/Foundation/StroikaPreComp.h"
8#include "Stroika/Foundation/Execution/Common.h"
9#include "Stroika/Foundation/Execution/OperationNotSupportedException.h"
17using namespace Stroika::Foundation::IO;
20using namespace Stroika::Foundation::Streams;
22using Memory::MakeSharedPtr;
28 constexpr size_t kDefaultBufSize_ = 2 * 1024;
35class MessageStartTextInputStreamBinaryAdapter::Rep_ final :
public InputStream::IRep<Character> {
41 , fAllDataReadBuf_{kDefaultBufSize_}
43 , fBufferFilledUpValidBytes_{0}
48 bool AssureHeaderSectionAvailable ()
51#if USE_NOISY_TRACE_IN_THIS_MODULE_
54 this->SeekRead (eFromStart, 0);
63 while (optional<span<Character>> o = Read (span{&c, &c + 1}, NoDataAvailableHandling::eDontBlock)) {
64 if (o->size () == 0) {
67 Assert (o->size () == 1);
78 DbgTrace (
"Looks like bad HTTP header (\\r)"_f);
89 this->SeekRead (eFromStart, 0);
93 DbgTrace (
"Looks like bad HTTP header (\\n)"_f);
112 sb <<
"Offset: "sv << fOffset_;
113 sb <<
", HighWaterMark: "sv << fBufferFilledUpValidBytes_;
116 case ToStringFormat::eAsBytes: {
117 for (
size_t i = 0; i < fBufferFilledUpValidBytes_; ++i) {
118 sb <<
"x{:x}, "_f(fAllDataReadBuf_[i]);
121 case ToStringFormat::eAsString: {
123 for (
Character c :
String::FromLatin1 (span{reinterpret_cast<const char*> (begin (fAllDataReadBuf_)), fBufferFilledUpValidBytes_})) {
144 virtual bool IsSeekable ()
const override
148 virtual void CloseRead ()
override
151 if (fSource_ !=
nullptr) {
154 Assert (fSource_ ==
nullptr);
156 virtual bool IsOpenRead ()
const override
158 return fSource_ !=
nullptr;
160 virtual optional<size_t> AvailableToRead ()
override
162 Require (IsOpenRead ());
163 if (fOffset_ < fBufferFilledUpValidBytes_) {
164 return fBufferFilledUpValidBytes_ - fOffset_;
169 virtual optional<SeekOffsetType> RemainingLength ()
override
171 Require (IsOpenRead ());
174 virtual optional<span<Character>> Read (span<Character> intoBuffer,
NoDataAvailableHandling blockFlag)
override
176 Require (not intoBuffer.empty ());
177 Require (IsOpenRead ());
179 Assert (fBufferFilledUpValidBytes_ >= fOffset_);
180 if (fBufferFilledUpValidBytes_ == fOffset_) {
181 size_t roomLeftInBuf = fAllDataReadBuf_.GetSize () - fBufferFilledUpValidBytes_;
182 if (roomLeftInBuf == 0) {
184 fAllDataReadBuf_.GrowToSize_uninitialized (fBufferFilledUpValidBytes_ + kDefaultBufSize_);
185 roomLeftInBuf = fAllDataReadBuf_.GetSize () - fBufferFilledUpValidBytes_;
187 Assert (roomLeftInBuf > 0);
192 size_t nBytesNeeded = intoBuffer.size ();
193 if (roomLeftInBuf > nBytesNeeded) {
194 roomLeftInBuf = nBytesNeeded;
198 byte* startReadAt = fAllDataReadBuf_.begin () + fBufferFilledUpValidBytes_;
199 size_t n = fSource_.ReadOrThrow (span{startReadAt, roomLeftInBuf}, blockFlag).size ();
200 Assert (n <= roomLeftInBuf);
202 fBufferFilledUpValidBytes_ += n;
207 for (
auto outChar = intoBuffer.begin (); outChar != intoBuffer.end (); ++outChar) {
208 if (fOffset_ < fBufferFilledUpValidBytes_) {
215 Ensure (outN <= intoBuffer.size ());
216 return intoBuffer.subspan (0, outN);
221 Require (IsOpenRead ());
227 Require (IsOpenRead ());
228 static const auto kException_ = range_error{
"seek"};
231 if (offset < 0) [[unlikely]] {
235 if (uOffset > fBufferFilledUpValidBytes_) [[unlikely]] {
239 fOffset_ =
static_cast<size_t> (offset);
244 if (newOffset < 0) [[unlikely]] {
248 if (uNewOffset > fBufferFilledUpValidBytes_) [[unlikely]] {
252 fOffset_ =
static_cast<size_t> (newOffset);
256 if (newOffset < 0) [[unlikely]] {
260 if (uNewOffset > fBufferFilledUpValidBytes_) [[unlikely]] {
264 fOffset_ =
static_cast<size_t> (newOffset);
267 Ensure ((0 <= fOffset_) and (fOffset_ <= fBufferFilledUpValidBytes_));
268 return GetReadOffset ();
276 size_t fBufferFilledUpValidBytes_;
286 return Ptr{MakeSharedPtr<Rep_> (src)};
299bool MessageStartTextInputStreamBinaryAdapter::Ptr::AssureHeaderSectionAvailable ()
301 return Debug::UncheckedDynamicCast<Rep_&> (
GetRepRWRef ()).AssureHeaderSectionAvailable ();
306 return Debug::UncheckedDynamicCast<const Rep_&> (GetRepConstRef ()).ToString (format);
NoDataAvailableHandling
If eDontBlock passed to most Stream APIs, then when the code would do a blocking read,...
int64_t SignedSeekOffsetType
constexpr char32_t GetCharacterCode() const noexcept
Return the char32_t UNICODE code-point associated with this character.
Similar to String, but intended to more efficiently construct a String. Mutable type (String is large...
String is like std::u32string, except it is much easier to use, often much more space efficient,...
NOT a real mutex - just a debugging infrastructure support tool so in debug builds can be assured thr...
shared_lock< const AssertExternallySynchronizedMutex > ReadContext
Instantiate AssertExternallySynchronizedMutex::ReadContext to designate an area of code where protect...
unique_lock< AssertExternallySynchronizedMutex > WriteContext
Instantiate AssertExternallySynchronizedMutex::WriteContext to designate an area of code where protec...
nonvirtual Characters::String ToString(ToStringFormat format=ToStringFormat::eDEFAULT) const
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
A Streams::Ptr<ELEMENT_TYPE> is a smart-pointer to a stream of elements of type T.
STRING_TYPE ToString(FLOAT_TYPE f, const ToStringOptions &options={})
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...