Hi all,
  the attached patch is a proposal for a couple of small extensions to
SBuf, which are meant to make it more API-compatible with std::string.

- it adds a "fill" operator: append(size_type n, char c)
- it aliases append(char) to push_back(char)
- it aliases reserveCapacity to reserve

Also a small fix:
- it marks the const begin() and end() methods as such

It is debateable whether reserveCapacity should be just renamed
instead of aliased; feedback is welcome.

The objective of this change will be clear in the followup rfc3986
patch, which is templatized in order to be available both to helpers
who use std::string and to squid using SBuf.

-- 
    Francesco
=== modified file 'src/SBuf.cc'
--- src/SBuf.cc	2015-10-29 23:08:05 +0000
+++ src/SBuf.cc	2015-12-20 18:28:01 +0000
@@ -221,40 +221,49 @@ SBuf::append(const SBuf &S)
 SBuf &
 SBuf::append(const char * S, size_type Ssize)
 {
     const Locker blobKeeper(this, S);
     if (S == NULL)
         return *this;
     if (Ssize == SBuf::npos)
         Ssize = strlen(S);
     debugs(24, 7, "from c-string to id " << id);
     // coverity[access_dbuff_in_call]
     return lowAppend(S, Ssize);
 }
 
 SBuf &
 SBuf::append(const char c)
 {
     return lowAppend(&c, 1);
 }
 
 SBuf&
+SBuf::append(size_type n, const char c)
+{
+    reserveSpace(n);
+    for (size_type j = 0; j < n; ++j)
+        lowAppend(&c, 1);
+    return *this;
+}
+
+SBuf&
 SBuf::Printf(const char *fmt, ...)
 {
     // with printf() the fmt or an arg might be a dangerous char*
     // NP: cant rely on vappendf() Locker because of clear()
     const Locker blobKeeper(this, buf());
 
     va_list args;
     va_start(args, fmt);
     clear();
     vappendf(fmt, args);
     va_end(args);
     return *this;
 }
 
 SBuf&
 SBuf::appendf(const char *fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
     vappendf(fmt, args);

=== modified file 'src/SBuf.h'
--- src/SBuf.h	2015-11-18 05:46:36 +0000
+++ src/SBuf.h	2015-12-28 11:25:13 +0000
@@ -217,40 +217,44 @@ public:
      * Copy a c-style string into a SBuf. Shortcut for SBuf.assign(S)
      * It is the caller's duty to free the imported string, if needed.
      * \note not \0-clean
      */
     SBuf& operator =(const char *S) {return assign(S);}
 
     /** reset the SBuf as if it was just created.
      *
      * Resets the SBuf to empty, memory is freed lazily.
      */
     void clear();
 
     /** Append operation
      *
      * Append the supplied SBuf to the current one; extend storage as needed.
      */
     SBuf& append(const SBuf & S);
 
     /// Append a single character. The character may be NUL (\0).
     SBuf& append(const char c);
+    SBuf& push_back(const char c) { return append(c); }
+
+    /// Append n consecutive copies of c
+    SBuf& append(size_type n, const char c);
 
     /** Append operation for C-style strings.
      *
      * Append the supplied c-string to the SBuf; extend storage
      * as needed.
      *
      * \param S the c string to be copied. Can be NULL.
      * \param Ssize how many bytes to import into the SBuf. If it is npos
      *              or unspecified, imports to end-of-cstring. If S is NULL,
      *              Ssize is ignored.
      * \note to append a std::string use the pattern
      *     cstr_append(stdstr.data(), stdstd.length())
      */
     SBuf& append(const char * S, size_type Ssize);
     SBuf& append(const char * S) { return append(S,npos); }
 
     /** Assignment operation with printf(3)-style definition
      * \note arguments may be evaluated more than once, be careful
      *       of side-effects
      */
@@ -495,40 +499,42 @@ public:
      * 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
      */
     void reserveSpace(size_type minSpace) {
         Must(minSpace <= maxSize);
         Must(length() <= maxSize - minSpace);
         reserveCapacity(length()+minSpace);
     }
 
     /** Request to guarantee the SBuf's store capacity
      *
      * After this method is called, the SBuf is guaranteed to have at least
      * 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
      */
     void reserveCapacity(size_type minCapacity);
+    // API-compatibility with std::string
+    void reserve(size_type minCapacity) { reserveCapacity(minCapacity); }
 
     /** slicing method
      *
      * Removes SBuf prefix and suffix, leaving a sequence of 'n'
      * bytes starting from position 'pos', first byte is at pos 0.
      * It is an in-place-modifying version of substr.
      * \param pos start sub-stringing from this byte. If it is
      *      npos or it is greater than the SBuf length, the SBuf is cleared and
      *      an empty SBuf is returned.
      * \param n maximum number of bytes of the resulting SBuf.
      *     npos means "to end of SBuf".
      *     if it is 0, the SBuf is cleared and an empty SBuf is returned.
      *     if it overflows the end of the SBuf, it is capped to the end of SBuf
      * \see substr, trim
      */
     SBuf& chop(size_type pos, size_type n = npos);
 
     /** Remove characters in the toremove set at the beginning, end or both
      *
      * \param toremove characters to be removed. Stops chomping at the first
@@ -631,53 +637,53 @@ public:
      * \return same as sscanf
      * \see man sscanf(3)
      */
     int scanf(const char *format, ...);
 
     /// converts all characters to lower case; \see man tolower(3)
     void toLower();
 
     /// converts all characters to upper case; \see man toupper(3)
     void toUpper();
 
     /** String export function
      * converts the SBuf to a legacy String, by copy.
      * \deprecated
      */
     String toString() const;
 
     /// std::string export function
     std::string toStdString() const { return std::string(buf(),length()); }
 
-    iterator begin() {
+    iterator begin() const {
         return iterator(*this, 0);
     }
 
-    iterator end() {
+    iterator end() const {
         return iterator(*this, length());
     }
 
-    reverse_iterator rbegin() {
+    reverse_iterator rbegin() const {
         return reverse_iterator(*this, length());
     }
 
-    reverse_iterator rend() {
+    reverse_iterator rend() const {
         return reverse_iterator(*this, 0);
     }
 
     // TODO: possibly implement erase() similar to std::string's erase
     // TODO: possibly implement a replace() call
 private:
 
     /**
      * Keeps SBuf's MemBlob alive in a blob-destroying context where
      * a seemingly unrelated memory pointer may belong to the same blob.
      * For [an extreme] example, consider: a.append(a).
      * Compared to an SBuf temporary, this class is optimized to
      * preserve blobs only if needed and to reduce debugging noise.
      */
     class Locker
     {
     public:
         Locker(SBuf *parent, const char *otherBuffer) {
             // lock if otherBuffer intersects the parents buffer area
             const MemBlob *blob = parent->store_.getRaw();

_______________________________________________
squid-dev mailing list
[email protected]
http://lists.squid-cache.org/listinfo/squid-dev

Reply via email to