23 readerSuppliedMemory_(initialSpace)
31 return extraMemory_ ? extraMemory_->rawContent() : readerSuppliedMemory_.data;
37 return extraMemory_ ? (extraMemory_->length() + extraMemory_->spaceSize()) : readerSuppliedMemory_.length;
43 return extraMemory_ ? extraMemory_->length() : readerSuppliedMemoryContentSize_;
55 assert(newByteCount <= spaceSize());
56 assert(memory() + contentSize() == newBytes);
60 extraMemory_->rawAppendFinish(newBytes, newByteCount);
62 readerSuppliedMemoryContentSize_ = *
IncreaseSum(readerSuppliedMemoryContentSize_, newByteCount);
64 assert(contentSize() <= capacity());
70 Assure(contentSize() >= parsedBytes);
72 extraMemory_->consume(parsedBytes);
74 readerSuppliedMemoryContentSize_ -= parsedBytes;
75 if (parsedBytes && readerSuppliedMemoryContentSize_)
76 memmove(readerSuppliedMemory_.data, memory() + parsedBytes, readerSuppliedMemoryContentSize_);
83 const auto size = spaceSize();
84 const auto start = extraMemory_ ?
85 extraMemory_->rawAppendStart(
size) :
86 (readerSuppliedMemory_.data + readerSuppliedMemoryContentSize_);
94 auto result = space();
95 Assure(result.length >= pageSize);
96 result.length = pageSize;
105 return StoreIOBuffer(contentSize(), 0,
const_cast<char*
>(memory()));
112 const auto capacityIncreaseAttempt =
IncreaseSum(contentSize(), minimumSpaceSize);
113 if (!capacityIncreaseAttempt)
114 throw TextException(
ToSBuf(
"no support for a single memory block of ", contentSize(),
'+', minimumSpaceSize,
" bytes"),
Here());
115 const auto newCapacity = *capacityIncreaseAttempt;
117 if (newCapacity <= capacity())
120 debugs(90, 7,
"growing to provide " << minimumSpaceSize <<
" in " << *
this);
123 extraMemory_->reserveCapacity(newCapacity);
127 newStorage.
append(readerSuppliedMemory_.data, readerSuppliedMemoryContentSize_);
128 extraMemory_ = std::move(newStorage);
130 Assure(spaceSize() >= minimumSpaceSize);
136 return extraMemory_ ? *extraMemory_ :
SBuf(content().data, content().length);
143 return extraMemory_->spaceSize();
145 assert(readerSuppliedMemoryContentSize_ <= readerSuppliedMemory_.length);
146 return readerSuppliedMemory_.length - readerSuppliedMemoryContentSize_;
154 *makeSpace(1).data = 0;
160 const auto bytesToPack = contentSize();
166 Assure(bytesToPack <= readerSuppliedMemory_.length);
168 auto result = readerSuppliedMemory_;
169 result.length = bytesToPack;
174 debugs(90, 7,
"quickly exporting " << result.length <<
" bytes via " << readerSuppliedMemory_);
176 debugs(90, 7,
"slowly exporting " << result.length <<
" bytes from " << extraMemory_->id <<
" back into " << readerSuppliedMemory_);
177 memmove(result.data, extraMemory_->rawContent(), result.length);
186 os <<
"size=" << contentSize();
189 os <<
" capacity=" << capacity();
190 os <<
" extra=" << extraMemory_->id;
195 if (readerSuppliedMemory_.length)
196 os <<
' ' << readerSuppliedMemory_;
#define Assure(condition)
#define Here()
source code location of the caller
std::optional< S > IncreaseSum(const S s, const T t)
argument pack expansion termination for IncreaseSum<S, T, Args...>()
void reserveCapacity(size_type minCapacity)
SBuf & append(const SBuf &S)
void consume(size_t)
get rid of previously appended() prefix of a given size
void growSpace(size_t)
makes sure we have the requested number of bytes, allocates enough memory if needed
size_t contentSize() const
the total number of append()ed bytes that were not consume()d
void print(std::ostream &) const
summarizes object state (for debugging)
const char * memory() const
a read-only content start (or nil for some zero-size buffers)
StoreIOBuffer content() const
ParsingBuffer()=default
creates buffer without any space or content
SBuf toSBuf() const
export content() into SBuf, avoiding content copying when possible
StoreIOBuffer makeSpace(size_t pageSize)
size_t spaceSize() const
the number of bytes in the space() buffer
size_t capacity() const
the maximum number of bytes we can store without allocating more space
void appended(const char *, size_t)
remember the new bytes received into the previously provided space()
an std::runtime_error with thrower location info
#define debugs(SECTION, LEVEL, CONTENT)
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf