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;
26 constexpr size_t kDefaultBufSize_ = 2 * 1024;
33class MessageStartTextInputStreamBinaryAdapter::Rep_ :
public InputStream::IRep<Character> {
39 , fAllDataReadBuf_{kDefaultBufSize_}
41 , fBufferFilledUpValidBytes_{0}
46 bool AssureHeaderSectionAvailable ()
49#if USE_NOISY_TRACE_IN_THIS_MODULE_
52 this->SeekRead (eFromStart, 0);
61 while (optional<span<Character>> o = Read (span{&c, &c + 1}, NoDataAvailableHandling::eDontBlock)) {
62 if (o->size () == 0) {
65 Assert (o->size () == 1);
76 DbgTrace (
"Looks like bad HTTP header (\\r)"_f);
87 this->SeekRead (eFromStart, 0);
91 DbgTrace (
"Looks like bad HTTP header (\\n)"_f);
110 sb <<
"Offset: "sv << fOffset_;
111 sb <<
", HighWaterMark: "sv << fBufferFilledUpValidBytes_;
114 case ToStringFormat::eAsBytes: {
115 for (
size_t i = 0; i < fBufferFilledUpValidBytes_; ++i) {
116 sb <<
"x{:x}, "_f(fAllDataReadBuf_[i]);
119 case ToStringFormat::eAsString: {
121 for (
Character c :
String::FromLatin1 (span{reinterpret_cast<const char*> (begin (fAllDataReadBuf_)), fBufferFilledUpValidBytes_})) {
149 if (fSource_ !=
nullptr) {
152 Assert (fSource_ ==
nullptr);
156 return fSource_ !=
nullptr;
160 Require (IsOpenRead ());
161 if (fOffset_ < fBufferFilledUpValidBytes_) {
162 return fBufferFilledUpValidBytes_ - fOffset_;
169 Require (IsOpenRead ());
174 Require (not intoBuffer.empty ());
175 Require (IsOpenRead ());
177 Assert (fBufferFilledUpValidBytes_ >= fOffset_);
178 if (fBufferFilledUpValidBytes_ == fOffset_) {
179 size_t roomLeftInBuf = fAllDataReadBuf_.GetSize () - fBufferFilledUpValidBytes_;
180 if (roomLeftInBuf == 0) {
182 fAllDataReadBuf_.GrowToSize_uninitialized (fBufferFilledUpValidBytes_ + kDefaultBufSize_);
183 roomLeftInBuf = fAllDataReadBuf_.GetSize () - fBufferFilledUpValidBytes_;
185 Assert (roomLeftInBuf > 0);
190 size_t nBytesNeeded = intoBuffer.size ();
191 if (roomLeftInBuf > nBytesNeeded) {
192 roomLeftInBuf = nBytesNeeded;
196 byte* startReadAt = fAllDataReadBuf_.begin () + fBufferFilledUpValidBytes_;
197 size_t n = fSource_.ReadOrThrow (span{startReadAt, roomLeftInBuf}, blockFlag).size ();
198 Assert (n <= roomLeftInBuf);
200 fBufferFilledUpValidBytes_ += n;
205 for (
auto outChar = intoBuffer.begin (); outChar != intoBuffer.end (); ++outChar) {
206 if (fOffset_ < fBufferFilledUpValidBytes_) {
213 Ensure (outN <= intoBuffer.size ());
214 return intoBuffer.subspan (0, outN);
219 Require (IsOpenRead ());
225 Require (IsOpenRead ());
226 static const auto kException_ = range_error{
"seek"};
229 if (offset < 0) [[unlikely]] {
233 if (uOffset > fBufferFilledUpValidBytes_) [[unlikely]] {
237 fOffset_ =
static_cast<size_t> (offset);
242 if (newOffset < 0) [[unlikely]] {
246 if (uNewOffset > fBufferFilledUpValidBytes_) [[unlikely]] {
250 fOffset_ =
static_cast<size_t> (newOffset);
254 if (newOffset < 0) [[unlikely]] {
258 if (uNewOffset > fBufferFilledUpValidBytes_) [[unlikely]] {
262 fOffset_ =
static_cast<size_t> (newOffset);
265 Ensure ((0 <= fOffset_) and (fOffset_ <= fBufferFilledUpValidBytes_));
274 size_t fBufferFilledUpValidBytes_;
284 return Ptr{make_shared<Rep_> (src)};
297bool MessageStartTextInputStreamBinaryAdapter::Ptr::AssureHeaderSectionAvailable ()
299 return Debug::UncheckedDynamicCast<Rep_&> (
GetRepRWRef ()).AssureHeaderSectionAvailable ();
304 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...
virtual bool IsSeekable() const =0
A Streams::Ptr<ELEMENT_TYPE> is a smart-pointer to a stream of elements of type T.
String ToString(T &&t, ARGS... args)
Return a debug-friendly, display version of the argument: not guaranteed parsable or usable except fo...
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...