/*
- * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
#define SQUID_SBUF_H
#include "base/InstanceId.h"
+#include "base/TextException.h"
#include "Debug.h"
#include "globals.h"
-#include "sbuf/Exceptions.h"
#include "sbuf/forward.h"
#include "sbuf/MemBlob.h"
#include "sbuf/Stats.h"
#include <climits>
-#include <cstdarg>
#include <iosfwd>
#include <iterator>
#if HAVE_UNISTD_H
protected:
SBufIterator(const SBuf &, size_type);
- const char *iter;
+ const char *iter = nullptr;
};
/** Reverse input const_iterator for SBufs
/// create an empty (zero-size) SBuf
SBuf();
SBuf(const SBuf &S);
-#if __cplusplus >= 201103L
SBuf(SBuf&& S) : store_(std::move(S.store_)), off_(S.off_), len_(S.len_) {
++stats.moves;
- S.store_=NULL; //RefCount supports NULL, and S is about to be destructed
- S.off_=0;
- S.len_=0;
+ S.store_ = nullptr; //RefCount supports nullptr, and S is about to be destructed
+ S.off_ = S.len_ = 0;
}
-#endif
/** Constructor: import c-style string
*
* Current SBuf will share backing store with the assigned one.
*/
SBuf& operator =(const SBuf & S) {return assign(S);}
-#if __cplusplus >= 201103L
SBuf& operator =(SBuf &&S) {
++stats.moves;
if (this != &S) {
}
return *this;
}
-#endif
/** Import a c-string into a SBuf, copying the data.
*
/** print SBuf contents and debug information about the SBuf to an ostream
*
- * Debug function, dumps to a stream informations on the current SBuf,
+ * Debug function, dumps to a stream information on the current SBuf,
* including low-level details and statistics.
*/
std::ostream& dump(std::ostream &os) const;
/** random-access read to any char within the SBuf.
*
- * \throw OutOfBoundsException when access is out of bounds
+ * \throw std::exception when access is out of bounds
* \note bounds is 0 <= pos < length(); caller must pay attention to signedness
*/
char at(size_type pos) const {checkAccessBounds(pos); return operator[](pos);}
*
* \param pos the position to be overwritten
* \param toset the value to be written
- * \throw OutOfBoundsException when pos is of bounds
+ * \throw std::exception when pos is of bounds
* \note bounds is 0 <= pos < length(); caller must pay attention to signedness
* \note performs a copy-on-write if needed.
*/
*/
SBuf consume(size_type n = npos);
- /// gets global statistic informations
+ /// gets global statistic information
static const SBufStats& GetStats();
/** Copy SBuf contents into user-supplied C buffer.
*/
const char* rawContent() const;
- /** Exports a writable pointer to the SBuf internal storage.
- * \warning Use with EXTREME caution, this is a dangerous operation.
- *
- * Returns a pointer to the first unused byte in the SBuf's storage,
- * which can be be used for appending. At least minSize bytes will
- * be available for writing.
- * The returned pointer must not be stored by the caller, as it will
- * be invalidated by the first call to a non-const method call
- * on the SBuf.
- * This call guarantees to never return NULL.
- * \see reserveSpace
- * \note Unlike reserveSpace(), this method does not guarantee exclusive
- * buffer ownership. It is instead optimized for a one writer
- * (appender), many readers scenario by avoiding unnecessary
- * copying and allocations.
- * \throw SBufTooBigException if the user tries to allocate too big a SBuf
- */
- char *rawSpace(size_type minSize);
+ /// \returns a buffer suitable for appending at most `anticipatedSize` bytes
+ /// The buffer must be used "immediately" because it is invalidated by most
+ /// non-constant SBuf method calls, including such calls against other SBuf
+ /// objects that just happen to share the same underlying MemBlob storage!
+ char *rawAppendStart(size_type anticipatedSize);
+
+ /// Updates SBuf metadata to reflect appending `actualSize` bytes to the
+ /// buffer returned by the corresponding rawAppendStart() call. Throws if
+ /// rawAppendStart(actualSize) would have returned a different value now.
+ /// \param start raw buffer previously returned by rawAppendStart()
+ /// \param actualSize the number of appended bytes
+ void rawAppendFinish(const char *start, size_type actualSize);
/** Obtain how much free space is available in the backing store.
*
*/
size_type spaceSize() const { return store_->spaceSize(); }
- /** Force a SBuf's size
- * \warning use with EXTREME caution, this is a dangerous operation
- *
- * Adapt the SBuf internal state after external interference
- * such as writing into it via rawSpace.
- * \throw TextException if SBuf doesn't have exclusive ownership of store
- * \throw SBufTooBigException if new size is bigger than available store space
- */
- void forceSize(size_type newSize);
-
/** exports a null-terminated reference to the SBuf internal storage.
* \warning ACCESSING RAW STORAGE IS DANGEROUS! DO NOT EVER USE
* THE RETURNED POINTER FOR WRITING
/** Get the length of the SBuf, as a signed integer
*
* Compatibility function for printf(3) which requires a signed int
- * \throw SBufTooBigException if the SBuf is too big for a signed integer
+ * \throw std::exception if buffer length does not fit a signed integer
*/
int plength() const {
- if (length()>INT_MAX)
- throw SBufTooBigException(__FILE__, __LINE__);
+ Must(length() <= INT_MAX);
return static_cast<int>(length());
}
* After the reserveSpace request, the SBuf is guaranteed to have at
* least minSpace bytes of unused backing store following the currently
* used portion and single ownership of the backing store.
- * \throw SBufTooBigException if the user tries to allocate too big a SBuf
+ * \throw std::exception if the user tries to allocate a too big SBuf
*/
void reserveSpace(size_type minSpace) {
Must(minSpace <= maxSize);
* minCapacity bytes of total buffer size, including the currently-used
* portion; it is also guaranteed that after this call this SBuf
* has unique ownership of the underlying memory store.
- * \throw SBufTooBigException if the user tries to allocate too big a SBuf
+ * \throw std::exception if the user tries to allocate a too big SBuf
*/
void reserveCapacity(size_type minCapacity);
friend class Locker;
MemBlob::Pointer store_; ///< memory block, possibly shared with other SBufs
- size_type off_; ///< our content start offset from the beginning of shared store_
- size_type len_; ///< number of our content bytes in shared store_
+ size_type off_ = 0; ///< our content start offset from the beginning of shared store_
+ size_type len_ = 0; ///< number of our content bytes in shared store_
static SBufStats stats; ///< class-wide statistics
/** obtain prototype store
/**
* Try to guesstimate how big a MemBlob to allocate.
- * The result is guarranteed to be to be at least the desired size.
+ * The result is guaranteed to be to be at least the desired size.
*/
size_type estimateCapacity(size_type desired) const {return (2*desired);}
void cow(size_type minsize = npos);
- void checkAccessBounds(size_type pos) const;
+ void checkAccessBounds(const size_type pos) const { Must(pos < length()); }
+
+ /** Exports a writable pointer to the SBuf internal storage.
+ * \warning Use with EXTREME caution, this is a dangerous operation.
+ *
+ * Returns a pointer to the first unused byte in the SBuf's storage,
+ * which can be be used for appending. At least minSize bytes will
+ * be available for writing.
+ * The returned pointer must not be stored by the caller, as it will
+ * be invalidated by the first call to a non-const method call
+ * on the SBuf.
+ * This call guarantees to never return nullptr.
+ * \see reserveSpace
+ * \note Unlike reserveSpace(), this method does not guarantee exclusive
+ * buffer ownership. It is instead optimized for a one writer
+ * (appender), many readers scenario by avoiding unnecessary
+ * copying and allocations.
+ * \throw std::exception if the user tries to allocate a too big SBuf
+ */
+ char *rawSpace(size_type minSize);
/** Low-level append operation
*