4#include "Stroika/Foundation/StroikaPreComp.h"
10#include "Stroika/Foundation/Execution/Exceptions.h"
11#include "Stroika/Foundation/Execution/Throw.h"
20using namespace Stroika::Foundation::Debug;
21using namespace Stroika::Foundation::Memory;
22using namespace Stroika::Foundation::Streams;
27#if qCompilerAndStdLib_specializeDeclarationRequiredSometimesToGenCode_Buggy
38 size_t len_ (
const initializer_list<pair<const byte*, const byte*>>& startEndPairs)
41 for (
auto i : startEndPairs) {
42 sz += (i.second - i.first);
46 size_t len_ (
const initializer_list<BLOB>& list2Concatenate)
49 for (
const auto& i : list2Concatenate) {
56BLOB::BasicRep_::BasicRep_ (
const initializer_list<pair<const byte*, const byte*>>& startEndPairs)
57 : fData{len_ (startEndPairs)}
59 byte* pb = fData.begin ();
60 for (
auto i : startEndPairs) {
61 auto itemSize{i.second - i.first};
63 (void)::memcpy (pb, i.first, itemSize);
67 Ensure (pb == fData.end ());
70BLOB::BasicRep_::BasicRep_ (
const initializer_list<BLOB>& list2Concatenate)
71 : fData{len_ (list2Concatenate)}
73 byte* pb = fData.begin ();
74 for (
const auto& i : list2Concatenate) {
75 auto itemSize{i.GetSize ()};
77 (void)::memcpy (pb, i.begin (), itemSize);
81 Ensure (pb == fData.end ());
84span<const byte> BLOB::BasicRep_::GetBounds ()
const
86 Ensure (fData.begin () <= fData.end ());
87#if qCompilerAndStdLib_span_requires_explicit_type_for_BLOBCVT_Buggy
88 return span<const byte>{fData.begin (), fData.end ()};
90 return span{fData.begin (), fData.end ()};
99span<const byte> BLOB::ZeroRep_::GetBounds ()
const
101 return span<const byte>{};
109BLOB::AdoptRep_::AdoptRep_ (
const byte* start,
const byte* end)
113 Require (start <= end);
116span<const byte> BLOB::AdoptRep_::GetBounds ()
const
118 Ensure (fStart <= fEnd);
119 return span<const byte>{fStart, fEnd};
127BLOB::AdoptAndDeleteRep_::AdoptAndDeleteRep_ (
const byte* start,
const byte* end)
131 Require (start <= end);
134BLOB::AdoptAndDeleteRep_::~AdoptAndDeleteRep_ ()
139span<const byte> BLOB::AdoptAndDeleteRep_::GetBounds ()
const
141 Ensure (fStart <= fEnd);
142 return span<const byte>{fStart, fEnd};
152 auto HexChar2Num_ = [] (
char c) ->
byte {
153 if (
'0' <= c and c <=
'9') [[likely]] {
154 return static_cast<byte> (c -
'0');
156 if (
'A' <= c and c <=
'F') [[likely]] {
157 return static_cast<byte> ((c -
'A') + 10);
159 if (
'a' <= c and c <=
'f') [[likely]] {
160 return static_cast<byte> ((c -
'a') + 10);
166 const char* e = s.
data () + s.size ();
167 for (
const char* i = s.data (); i < e; ++i) {
168 if (isspace (*i)) [[unlikely]] {
171 byte b = HexChar2Num_ (*i);
173 if (i == e) [[unlikely]] {
177 b = byte (uint8_t (b << 4) + uint8_t (HexChar2Num_ (*i)));
180 return BLOB{buf.begin (), buf.end ()};
193 return Cryptography::Encoding::Algorithm::Base64::Decode (s);
205 using namespace Streams;
207 BLOBBINSTREAM_ (
const BLOB& b)
208 : InputStream::
Ptr<byte>{Memory::MakeSharedPtr<REP> (b)}
212 bool fIsOpenForRead_{
true};
217 , fCur{fSavedBLOB_.begin ()}
218 , fStart{fSavedBLOB_.begin ()}
219 , fEnd{fSavedBLOB_.end ()}
222 virtual bool IsSeekable ()
const override
226 virtual void CloseRead ()
override
228 fIsOpenForRead_ =
false;
229 Require (not IsOpenRead ());
231 virtual bool IsOpenRead ()
const override
233 return fIsOpenForRead_;
235 virtual optional<size_t> AvailableToRead ()
override
237 Require (IsOpenRead ());
241 virtual optional<SeekOffsetType> RemainingLength ()
override
244 Require (IsOpenRead ());
247 virtual optional<span<byte>> Read (span<byte> intoBuffer, [[maybe_unused]]
NoDataAvailableHandling blockFlag)
override
249 Require (not intoBuffer.empty ());
251 size_t bytesToRead = intoBuffer.size ();
252 size_t bytesLeft = fEnd - fCur;
253 bytesToRead = min (bytesLeft, bytesToRead);
254 CopyBytes (span{fCur, bytesToRead}, intoBuffer);
256 return intoBuffer.subspan (0, bytesToRead);
260 Require (IsOpenRead ());
262 return fCur - fStart;
266 static const auto kException_ = range_error{
"seek"};
268 Require (IsOpenRead ());
271 if (offset < 0) [[unlikely]] {
274 if (offset > (fEnd - fStart)) [[unlikely]] {
277 fCur = fStart + offset;
282 if (newOffset < 0) [[unlikely]] {
285 if (newOffset > (fEnd - fStart)) [[unlikely]] {
288 fCur = fStart + newOffset;
292 if (newOffset < 0) [[unlikely]] {
295 if (newOffset > (fEnd - fStart)) [[unlikely]] {
298 fCur = fStart + newOffset;
301 Ensure ((fStart <= fCur) and (fCur <= fEnd));
302 return GetReadOffset ();
315 return BLOBBINSTREAM_{*
this};
325 for (
byte b : *this) {
326 if (cnt++ > maxBytesToShow) {
327#if qCompilerAndStdLib_crash_compiling_break_in_forLoop_Buggy
333 sb <<
"{:02x}"_f(
static_cast<unsigned int> (b));
341 return AsBase64 ({});
346 return Cryptography::Encoding::Algorithm::Base64::Encode (*
this, o);
355 else if (count <= 2) {
357 for (
unsigned int i = 1; i < count; ++i) {
364 span<const byte> b2c = As<span<const byte>> ();
366 target.
reserve (count * b2c.size ());
367 for (
unsigned int i = 0; i < count; ++i) {
368 target.push_back (b2c);
370 return BLOB{span{target}};
376 Require (startAt <= endAt);
377 Require (endAt <
size ());
385 bool allBytesAscii = [
this] () {
return Character::IsASCII (Memory::SpanBytesCast<span<const char>> (this->
As<span<const byte>> ())); }();
386 auto quoteAscii4Display = [] (
const String& s) {
389 if (
size () > maxBytesToShow) {
391 return "[{} bytes: '{}' ...]"_f(
size (), quoteAscii4Display (
String{this->As<string> ()}));
395 size_t maxStrLen = maxBytesToShow < numeric_limits<size_t>::max () / 2 ? maxBytesToShow * 2 : maxBytesToShow;
401 return "[{} bytes: '{}']"_f(
size (), quoteAscii4Display (
String{this->As<string> ()}));
404 return "[{} bytes: {}]"_f(
size (),
AsHex ());
conditional_t< qStroika_Foundation_Memory_PreferBlockAllocation and andTrueCheck, BlockAllocationUseHelper< T >, Common::Empty > UseBlockAllocationIfAppropriate
Use this to enable block allocation for a particular class. Beware of subclassing.
NoDataAvailableHandling
If eDontBlock passed to most Stream APIs, then when the code would do a blocking read,...
int64_t SignedSeekOffsetType
Similar to String, but intended to more efficiently construct a String. Mutable type (String is large...
nonvirtual String str() const
String is like std::u32string, except it is much easier to use, often much more space efficient,...
nonvirtual String LimitLength(size_t maxLen, StringShorteningPreference keepPref=StringShorteningPreference::ePreferKeepLeft) const
return the first maxLen (or fewer if string shorter) characters of this string (adding ellipsis if tr...
nonvirtual String ReplaceAll(const RegularExpression ®Ex, const String &with) const
nonvirtual T AsASCII() const
static optional< span< const CHAR_TYPE > > PeekData(const PeekSpanData &pds)
return the constant character data inside the string in the form of a span or nullopt if not availabl...
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 STRING_TYPE AsBase64() const
nonvirtual Characters::String ToString(size_t maxBytesToShow=80) const
nonvirtual BLOB Repeat(unsigned int count) const
static BLOB FromHex(const char *b)
Convert string of hex bytes to BLOB.
nonvirtual BLOB Slice(size_t startAt, size_t endAt) const
nonvirtual const byte * begin() const
nonvirtual STRING_TYPE AsHex(size_t maxBytesToShow=numeric_limits< size_t >::max()) const
static BLOB FromBase64(const char *b)
Convert string of base64 bytes to BLOB.
nonvirtual size_t size() const
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
nonvirtual pointer data() noexcept
returns a (possibly const) pointer to the start of the live buffer data. This return value can be inv...
nonvirtual void push_back(Common::ArgByValueType< T > e)
nonvirtual void reserve(size_t newCapacity, bool atLeast=true)
A Streams::Ptr<ELEMENT_TYPE> is a smart-pointer to a stream of elements of type T.
char ASCII
Stroika's string/character classes treat 'char' as being an ASCII character.
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...