source: src/router/squid/src/sbuf/SBuf.h @ 32165

Last change on this file since 32165 was 32165, checked in by brainslayer, 3 months ago

update squid

File size: 27.5 KB
Line 
1/*
2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9/* DEBUG: section 24    SBuf */
10
11#ifndef SQUID_SBUF_H
12#define SQUID_SBUF_H
13
14#include "base/InstanceId.h"
15#include "Debug.h"
16#include "globals.h"
17#include "sbuf/Exceptions.h"
18#include "sbuf/forward.h"
19#include "sbuf/MemBlob.h"
20#include "sbuf/Stats.h"
21
22#include <climits>
23#include <cstdarg>
24#include <iosfwd>
25#include <iterator>
26#if HAVE_UNISTD_H
27#include <unistd.h>
28#endif
29
30/* SBuf placeholder for printf */
31#ifndef SQUIDSBUFPH
32#define SQUIDSBUFPH "%.*s"
33#define SQUIDSBUFPRINT(s) (s).plength(),(s).rawContent()
34#endif /* SQUIDSBUFPH */
35
36// TODO: move within SBuf and rename
37typedef enum {
38    caseSensitive,
39    caseInsensitive
40} SBufCaseSensitive;
41
42class CharacterSet;
43
44/** Forward input const_iterator for SBufs
45 *
46 * Please note that any operation on the underlying SBuf may invalidate
47 * all iterators over it, resulting in undefined behavior by them.
48 */
49class SBufIterator : public std::iterator<std::input_iterator_tag, char>
50{
51public:
52    friend class SBuf;
53    typedef MemBlob::size_type size_type;
54    bool operator==(const SBufIterator &s) const;
55    bool operator!=(const SBufIterator &s) const;
56
57    const char &operator*() const { return *iter; }
58    SBufIterator& operator++() { ++iter; return *this; }
59
60protected:
61    SBufIterator(const SBuf &, size_type);
62
63    const char *iter = nullptr;
64};
65
66/** Reverse input const_iterator for SBufs
67 *
68 * Please note that any operation on the underlying SBuf may invalidate
69 * all iterators over it, resulting in undefined behavior by them.
70 */
71class SBufReverseIterator : public SBufIterator
72{
73    friend class SBuf;
74public:
75    SBufReverseIterator& operator++() { --iter; return *this;}
76    const char &operator*() const { return *(iter-1); }
77protected:
78    SBufReverseIterator(const SBuf &s, size_type sz) : SBufIterator(s,sz) {}
79};
80
81/**
82 * A String or Buffer.
83 * Features: refcounted backing store, cheap copy and sub-stringing
84 * operations, copy-on-write to isolate change operations to each instance.
85 * Where possible, we're trying to mimic std::string's interface.
86 */
87class SBuf
88{
89public:
90    typedef MemBlob::size_type size_type;
91    typedef SBufIterator const_iterator;
92    typedef SBufReverseIterator const_reverse_iterator;
93    static const size_type npos = 0xffffffff; // max(uint32_t)
94
95    /// Maximum size of a SBuf. By design it MUST be < MAX(size_type)/2. Currently 256Mb.
96    static const size_type maxSize = 0xfffffff;
97
98    /// create an empty (zero-size) SBuf
99    SBuf();
100    SBuf(const SBuf &S);
101    SBuf(SBuf&& S) : store_(std::move(S.store_)), off_(S.off_), len_(S.len_) {
102        ++stats.moves;
103        S.store_ = nullptr; //RefCount supports nullptr, and S is about to be destructed
104        S.off_ = S.len_ = 0;
105    }
106
107    /** Constructor: import c-style string
108     *
109     * Create a new SBuf containing a COPY of the contents of the
110     * c-string
111     * \param S the c string to be copied
112     * \param n how many bytes to import into the SBuf. If it is npos
113     *              or unspecified, imports to end-of-cstring
114     * \note it is the caller's responsibility not to go out of bounds
115     * \note bounds is 0 <= pos < length(); caller must pay attention to signedness
116     */
117    explicit SBuf(const char *S, size_type n);
118    explicit SBuf(const char *S);
119
120    /// Constructor: import std::string. Contents are copied.
121    explicit SBuf(const std::string &s);
122
123    ~SBuf();
124
125    /** Explicit assignment.
126     *
127     * Current SBuf will share backing store with the assigned one.
128     */
129    SBuf& assign(const SBuf &S);
130
131    /** Assignment operator.
132     *
133     * Current SBuf will share backing store with the assigned one.
134     */
135    SBuf& operator =(const SBuf & S) {return assign(S);}
136#if __cplusplus >= 201103L
137    SBuf& operator =(SBuf &&S) {
138        ++stats.moves;
139        if (this != &S) {
140            store_ = std::move(S.store_);
141            off_ = S.off_;
142            len_ = S.len_;
143            S.store_ = NULL; //RefCount supports NULL, and S is about to be destructed
144            S.off_ = 0;
145            S.len_ = 0;
146        }
147        return *this;
148    }
149#endif
150
151    /** Import a c-string into a SBuf, copying the data.
152     *
153     * It is the caller's duty to free the imported string, if needed.
154     * \param S the c string to be copied
155     * \param n how many bytes to import into the SBuf. If it is npos
156     *              or unspecified, imports to end-of-cstring
157     * \note it is the caller's responsibility not to go out of bounds
158     * \note to assign a std::string use the pattern:
159     *    assign(stdstr.data(), stdstd.length())
160     */
161    SBuf& assign(const char *S, size_type n);
162    SBuf& assign(const char *S) {return assign(S,npos);}
163
164    /** Assignment operator. Copy a NULL-terminated c-style string into a SBuf.
165     *
166     * Copy a c-style string into a SBuf. Shortcut for SBuf.assign(S)
167     * It is the caller's duty to free the imported string, if needed.
168     * \note not \0-clean
169     */
170    SBuf& operator =(const char *S) {return assign(S);}
171
172    /** reset the SBuf as if it was just created.
173     *
174     * Resets the SBuf to empty, memory is freed lazily.
175     */
176    void clear();
177
178    /** Append operation
179     *
180     * Append the supplied SBuf to the current one; extend storage as needed.
181     */
182    SBuf& append(const SBuf & S);
183
184    /// Append a single character. The character may be NUL (\0).
185    SBuf& append(const char c);
186
187    /** Append operation for C-style strings.
188     *
189     * Append the supplied c-string to the SBuf; extend storage
190     * as needed.
191     *
192     * \param S the c string to be copied. Can be NULL.
193     * \param Ssize how many bytes to import into the SBuf. If it is npos
194     *              or unspecified, imports to end-of-cstring. If S is NULL,
195     *              Ssize is ignored.
196     * \note to append a std::string use the pattern
197     *     cstr_append(stdstr.data(), stdstd.length())
198     */
199    SBuf& append(const char * S, size_type Ssize);
200    SBuf& append(const char * S) { return append(S,npos); }
201
202    /** Assignment operation with printf(3)-style definition
203     * \note arguments may be evaluated more than once, be careful
204     *       of side-effects
205     */
206    SBuf& Printf(const char *fmt, ...);
207
208    /** Append operation with printf-style arguments
209     * \note arguments may be evaluated more than once, be careful
210     *       of side-effects
211     */
212    SBuf& appendf(const char *fmt, ...);
213
214    /** Append operation, with vsprintf(3)-style arguments.
215     * \note arguments may be evaluated more than once, be careful
216     *       of side-effects
217     */
218    SBuf& vappendf(const char *fmt, va_list vargs);
219
220    /// print the SBuf contents to the supplied ostream
221    std::ostream& print(std::ostream &os) const;
222
223    /** print SBuf contents and debug information about the SBuf to an ostream
224     *
225     * Debug function, dumps to a stream informations on the current SBuf,
226     * including low-level details and statistics.
227     */
228    std::ostream& dump(std::ostream &os) const;
229
230    /** random-access read to any char within the SBuf
231     *
232     * does not check access bounds. If you need that, use at()
233     */
234    char operator [](size_type pos) const {++stats.getChar; return store_->mem[off_+pos];}
235
236    /** random-access read to any char within the SBuf.
237     *
238     * \throw OutOfBoundsException when access is out of bounds
239     * \note bounds is 0 <= pos < length(); caller must pay attention to signedness
240     */
241    char at(size_type pos) const {checkAccessBounds(pos); return operator[](pos);}
242
243    /** direct-access set a byte at a specified operation.
244     *
245     * \param pos the position to be overwritten
246     * \param toset the value to be written
247     * \throw OutOfBoundsException when pos is of bounds
248     * \note bounds is 0 <= pos < length(); caller must pay attention to signedness
249     * \note performs a copy-on-write if needed.
250     */
251    void setAt(size_type pos, char toset);
252
253    /** compare to other SBuf, str(case)cmp-style
254     *
255     * \param isCaseSensitive one of caseSensitive or caseInsensitive
256     * \param n compare up to this many bytes. if npos (default), compare whole SBufs
257     * \retval >0 argument of the call is greater than called SBuf
258     * \retval <0 argument of the call is smaller than called SBuf
259     * \retval 0  argument of the call has the same contents of called SBuf
260     */
261    int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive, const size_type n) const;
262    int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive) const {
263        return compare(S, isCaseSensitive, npos);
264    }
265
266    /// shorthand version for compare()
267    inline int cmp(const SBuf &S, const size_type n) const {
268        return compare(S,caseSensitive,n);
269    }
270    inline int cmp(const SBuf &S) const {
271        return compare(S,caseSensitive,npos);
272    }
273
274    /// shorthand version for case-insensitive compare()
275    inline int caseCmp(const SBuf &S, const size_type n) const {
276        return compare(S,caseInsensitive,n);
277    }
278    inline int caseCmp(const SBuf &S) const {
279        return compare(S,caseInsensitive,npos);
280    }
281
282    /// Comparison with a C-string.
283    int compare(const char *s, const SBufCaseSensitive isCaseSensitive, const size_type n) const;
284    int compare(const char *s, const SBufCaseSensitive isCaseSensitive) const {
285        return compare(s,isCaseSensitive,npos);
286    }
287
288    /// Shorthand version for C-string compare().
289    inline int cmp(const char *S, const size_type n) const {
290        return compare(S,caseSensitive,n);
291    }
292    inline int cmp(const char *S) const {
293        return compare(S,caseSensitive,npos);
294    }
295
296    /// Shorthand version for case-insensitive C-string compare().
297    inline int caseCmp(const char *S, const size_type n) const {
298        return compare(S,caseInsensitive,n);
299    }
300    inline int caseCmp(const char *S) const {
301        return compare(S,caseInsensitive,npos);
302    }
303
304    /** check whether the entire supplied argument is a prefix of the SBuf.
305     *  \param S the prefix to match against
306     *  \param isCaseSensitive one of caseSensitive or caseInsensitive
307     *  \retval true argument is a prefix of the SBuf
308     */
309    bool startsWith(const SBuf &S, const SBufCaseSensitive isCaseSensitive = caseSensitive) const;
310
311    bool operator ==(const SBuf & S) const;
312    bool operator !=(const SBuf & S) const;
313    bool operator <(const SBuf &S) const {return (cmp(S) < 0);}
314    bool operator >(const SBuf &S) const {return (cmp(S) > 0);}
315    bool operator <=(const SBuf &S) const {return (cmp(S) <= 0);}
316    bool operator >=(const SBuf &S) const {return (cmp(S) >= 0);}
317
318    /** Consume bytes at the head of the SBuf
319     *
320     * Consume N chars at SBuf head, or to SBuf's end,
321     * whichever is shorter. If more bytes are consumed than available,
322     * the SBuf is emptied
323     * \param n how many bytes to remove; could be zero.
324     *     npos (or no argument) means 'to the end of SBuf'
325     * \return a new SBuf containing the consumed bytes.
326     */
327    SBuf consume(size_type n = npos);
328
329    /// gets global statistic informations
330    static const SBufStats& GetStats();
331
332    /** Copy SBuf contents into user-supplied C buffer.
333     *
334     * Export a copy of the SBuf's contents into the user-supplied
335     * buffer, up to the user-supplied-length. No zero-termination is performed
336     * \return num the number of actually-copied chars.
337     */
338    size_type copy(char *dest, size_type n) const;
339
340    /** exports a pointer to the SBuf internal storage.
341     * \warning ACCESSING RAW STORAGE IS DANGEROUS!
342     *
343     * Returns a ead-only pointer to SBuf's content. No terminating null
344     * character is appended (use c_str() for that).
345     * The returned value points to an internal location whose contents
346     * are guaranteed to remain unchanged only until the next call
347     * to a non-constant member function of the SBuf object. Such a
348     * call may be implicit (e.g., when SBuf is destroyed
349     * upon leaving the current context).
350     * This is a very UNSAFE way of accessing the data.
351     * This call never returns NULL.
352     * \see c_str
353     * \note the memory management system guarantees that the exported region
354     *    of memory will remain valid if the caller keeps holding
355     *    a valid reference to the SBuf object and does not write or append to
356     *    it. For example:
357     * \code
358     * SBuf foo("some string");
359     * const char *bar = foo.rawContent();
360     * doSomething(bar); //safe
361     * foo.append(" other string");
362     * doSomething(bar); //unsafe
363     * \endcode
364     */
365    const char* rawContent() const;
366
367    /** Exports a writable pointer to the SBuf internal storage.
368     * \warning Use with EXTREME caution, this is a dangerous operation.
369     *
370     * Returns a pointer to the first unused byte in the SBuf's storage,
371     * which can be be used for appending. At least minSize bytes will
372     * be available for writing.
373     * The returned pointer must not be stored by the caller, as it will
374     * be invalidated by the first call to a non-const method call
375     * on the SBuf.
376     * This call guarantees to never return NULL.
377     * \see reserveSpace
378     * \note Unlike reserveSpace(), this method does not guarantee exclusive
379     *       buffer ownership. It is instead optimized for a one writer
380     *       (appender), many readers scenario by avoiding unnecessary
381     *       copying and allocations.
382     * \throw SBufTooBigException if the user tries to allocate too big a SBuf
383     */
384    char *rawSpace(size_type minSize);
385
386    /** Obtain how much free space is available in the backing store.
387     *
388     * \note: unless the client just cow()ed, it is not guaranteed that
389     *        the free space can be used.
390     */
391    size_type spaceSize() const { return store_->spaceSize(); }
392
393    /** Force a SBuf's size
394     * \warning use with EXTREME caution, this is a dangerous operation
395     *
396     * Adapt the SBuf internal state after external interference
397     * such as writing into it via rawSpace.
398     * \throw TextException if SBuf doesn't have exclusive ownership of store
399     * \throw SBufTooBigException if new size is bigger than available store space
400     */
401    void forceSize(size_type newSize);
402
403    /** exports a null-terminated reference to the SBuf internal storage.
404     * \warning ACCESSING RAW STORAGE IS DANGEROUS! DO NOT EVER USE
405     *  THE RETURNED POINTER FOR WRITING
406     *
407     * The returned value points to an internal location whose contents
408     * are guaranteed to remain unchanged only until the next call
409     * to a non-constant member function of the SBuf object. Such a
410     * call may be implicit (e.g., when SBuf is destroyed
411     * upon leaving the current context).
412     * This is a very UNSAFE way of accessing the data.
413     * This call never returns NULL.
414     * \see rawContent
415     * \note the memory management system guarantees that the exported region
416     *    of memory will remain valid will remain valid only if the
417     *    caller keeps holding a valid reference to the SBuf object and
418     *    does not write or append to it
419     */
420    const char* c_str();
421
422    /// Returns the number of bytes stored in SBuf.
423    size_type length() const {return len_;}
424
425    /** Get the length of the SBuf, as a signed integer
426     *
427     * Compatibility function for printf(3) which requires a signed int
428     * \throw SBufTooBigException if the SBuf is too big for a signed integer
429     */
430    int plength() const {
431        if (length()>INT_MAX)
432            throw SBufTooBigException(__FILE__, __LINE__);
433        return static_cast<int>(length());
434    }
435
436    /** Check whether the SBuf is empty
437     *
438     * \return true if length() == 0
439     */
440    bool isEmpty() const {return (len_==0);}
441
442    /** Request to guarantee the SBuf's free store space.
443     *
444     * After the reserveSpace request, the SBuf is guaranteed to have at
445     * least minSpace bytes of unused backing store following the currently
446     * used portion and single ownership of the backing store.
447     * \throw SBufTooBigException if the user tries to allocate too big a SBuf
448     */
449    void reserveSpace(size_type minSpace) {
450        Must(minSpace <= maxSize);
451        Must(length() <= maxSize - minSpace);
452        reserveCapacity(length()+minSpace);
453    }
454
455    /** Request to guarantee the SBuf's store capacity
456     *
457     * After this method is called, the SBuf is guaranteed to have at least
458     * minCapacity bytes of total buffer size, including the currently-used
459     * portion; it is also guaranteed that after this call this SBuf
460     * has unique ownership of the underlying memory store.
461     * \throw SBufTooBigException if the user tries to allocate too big a SBuf
462     */
463    void reserveCapacity(size_type minCapacity);
464
465    /** Accommodate caller's requirements regarding SBuf's storage if possible.
466     *
467     * \return spaceSize(), which may be zero
468     */
469    size_type reserve(const SBufReservationRequirements &requirements);
470
471    /** slicing method
472     *
473     * Removes SBuf prefix and suffix, leaving a sequence of 'n'
474     * bytes starting from position 'pos', first byte is at pos 0.
475     * It is an in-place-modifying version of substr.
476     * \param pos start sub-stringing from this byte. If it is
477     *      npos or it is greater than the SBuf length, the SBuf is cleared and
478     *      an empty SBuf is returned.
479     * \param n maximum number of bytes of the resulting SBuf.
480     *     npos means "to end of SBuf".
481     *     if it is 0, the SBuf is cleared and an empty SBuf is returned.
482     *     if it overflows the end of the SBuf, it is capped to the end of SBuf
483     * \see substr, trim
484     */
485    SBuf& chop(size_type pos, size_type n = npos);
486
487    /** Remove characters in the toremove set at the beginning, end or both
488     *
489     * \param toremove characters to be removed. Stops chomping at the first
490     *        found char not in the set
491     * \param atBeginning if true (default), strips at the beginning of the SBuf
492     * \param atEnd if true (default), strips at the end of the SBuf
493     */
494    SBuf& trim(const SBuf &toRemove, bool atBeginning = true, bool atEnd = true);
495
496    /** Extract a part of the current SBuf.
497     *
498     * Return a fresh a fresh copy of a portion the current SBuf, which is
499     * left untouched. The same parameter convetions apply as for chop.
500     * \see trim, chop
501     */
502    SBuf substr(size_type pos, size_type n = npos) const;
503
504    /** Find first occurrence of character in SBuf
505     *
506     * Returns the index in the SBuf of the first occurrence of char c.
507     * \return npos if the char was not found
508     * \param startPos if specified, ignore any occurrences before that position
509     *     if startPos is npos or greater than length() npos is always returned
510     *     if startPos is less than zero, it is ignored
511     */
512    size_type find(char c, size_type startPos = 0) const;
513
514    /** Find first occurrence of SBuf in SBuf.
515     *
516     * Returns the index in the SBuf of the first occurrence of the
517     * sequence contained in the str argument.
518     * \param startPos if specified, ignore any occurrences before that position
519     *     if startPos is npos or greater than length() npos is always returned
520     * \return npos if the SBuf was not found
521     */
522    size_type find(const SBuf & str, size_type startPos = 0) const;
523
524    /** Find last occurrence of character in SBuf
525     *
526     * Returns the index in the SBuf of the last occurrence of char c.
527     * \return npos if the char was not found
528     * \param endPos if specified, ignore any occurrences after that position.
529     *   if npos or greater than length(), the whole SBuf is considered
530     */
531    size_type rfind(char c, size_type endPos = npos) const;
532
533    /** Find last occurrence of SBuf in SBuf
534     *
535     * Returns the index in the SBuf of the last occurrence of the
536     * sequence contained in the str argument.
537     * \return npos if the sequence  was not found
538     * \param endPos if specified, ignore any occurrences after that position
539     *   if npos or greater than length(), the whole SBuf is considered
540     */
541    size_type rfind(const SBuf &str, size_type endPos = npos) const;
542
543    /** Find first occurrence of character of set in SBuf
544     *
545     * Finds the first occurrence of ANY of the characters in the supplied set in
546     * the SBuf.
547     * \return npos if no character in the set could be found
548     * \param startPos if specified, ignore any occurrences before that position
549     *   if npos, then npos is always returned
550     *
551     * TODO: rename to camelCase
552     */
553    size_type findFirstOf(const CharacterSet &set, size_type startPos = 0) const;
554
555    /** Find last occurrence of character of set in SBuf
556     *
557     * Finds the last occurrence of ANY of the characters in the supplied set in
558     * the SBuf.
559     * \return npos if no character in the set could be found
560     * \param endPos if specified, ignore any occurrences after that position
561     *   if npos, the entire SBuf is searched
562     */
563    size_type findLastOf(const CharacterSet &set, size_type endPos = npos) const;
564
565    /** Find first occurrence character NOT in character set
566     *
567     * \return npos if all characters in the SBuf are from set
568     * \param startPos if specified, ignore any occurrences before that position
569     *   if npos, then npos is always returned
570     *
571     * TODO: rename to camelCase
572     */
573    size_type findFirstNotOf(const CharacterSet &set, size_type startPos = 0) const;
574
575    /** Find last occurrence character NOT in character set
576     *
577     * \return npos if all characters in the SBuf are from set
578     * \param endPos if specified, ignore any occurrences after that position
579     *   if npos, then the entire SBuf is searched
580     */
581    size_type findLastNotOf(const CharacterSet &set, size_type endPos = npos) const;
582
583    /// converts all characters to lower case; \see man tolower(3)
584    void toLower();
585
586    /// converts all characters to upper case; \see man toupper(3)
587    void toUpper();
588
589    /// std::string export function
590    std::string toStdString() const { return std::string(buf(),length()); }
591
592    const_iterator begin() const {
593        return const_iterator(*this, 0);
594    }
595
596    const_iterator end() const {
597        return const_iterator(*this, length());
598    }
599
600    const_reverse_iterator rbegin() const {
601        return const_reverse_iterator(*this, length());
602    }
603
604    const_reverse_iterator rend() const {
605        return const_reverse_iterator(*this, 0);
606    }
607
608    // TODO: possibly implement erase() similar to std::string's erase
609    // TODO: possibly implement a replace() call
610
611    /// SBuf object identifier meant for test cases and debugging.
612    /// Does not change when object does, including during assignment.
613    const InstanceId<SBuf> id;
614
615private:
616
617    /**
618     * Keeps SBuf's MemBlob alive in a blob-destroying context where
619     * a seemingly unrelated memory pointer may belong to the same blob.
620     * For [an extreme] example, consider: a.append(a).
621     * Compared to an SBuf temporary, this class is optimized to
622     * preserve blobs only if needed and to reduce debugging noise.
623     */
624    class Locker
625    {
626    public:
627        Locker(SBuf *parent, const char *otherBuffer) {
628            // lock if otherBuffer intersects the parents buffer area
629            const MemBlob *blob = parent->store_.getRaw();
630            if (blob->mem <= otherBuffer && otherBuffer < (blob->mem + blob->capacity))
631                locket = blob;
632        }
633    private:
634        MemBlob::Pointer locket;
635    };
636    friend class Locker;
637
638    MemBlob::Pointer store_; ///< memory block, possibly shared with other SBufs
639    size_type off_ = 0; ///< our content start offset from the beginning of shared store_
640    size_type len_ = 0; ///< number of our content bytes in shared store_
641    static SBufStats stats; ///< class-wide statistics
642
643    /** obtain prototype store
644     *
645     * Just-created SBufs all share to the same MemBlob.
646     * This call instantiates and returns it.
647     */
648    static MemBlob::Pointer GetStorePrototype();
649
650    /**
651     * obtains a char* to the beginning of this SBuf in memory.
652     * \note the obtained string is NOT null-terminated.
653     */
654    char * buf() const {return (store_->mem+off_);}
655
656    /** returns the pointer to the first char after this SBuf end
657     *
658     *  No checks are made that the space returned is safe, checking that is
659     *  up to the caller.
660     */
661    char * bufEnd() const {return (store_->mem+off_+len_);}
662
663    /**
664     * Try to guesstimate how big a MemBlob to allocate.
665     * The result is guarranteed to be to be at least the desired size.
666     */
667    size_type estimateCapacity(size_type desired) const {return (2*desired);}
668
669    void reAlloc(size_type newsize);
670
671    void cow(size_type minsize = npos);
672
673    void checkAccessBounds(size_type pos) const;
674
675    /** Low-level append operation
676     *
677     * Takes as input a contiguous area of memory and appends its contents
678     * to the SBuf, taking care of memory management. Does no bounds checking
679     * on the supplied memory buffer, it is the duty of the caller to ensure
680     * that the supplied area is valid.
681     */
682    SBuf& lowAppend(const char * memArea, size_type areaSize);
683};
684
685/// Named SBuf::reserve() parameters. Defaults ask for and restrict nothing.
686class SBufReservationRequirements
687{
688public:
689    typedef SBuf::size_type size_type;
690
691    /*
692     * Parameters are listed in the reverse order of importance: Satisfaction of
693     * the lower-listed requirements may violate the higher-listed requirements.
694     * For example, idealSpace has no effect unless it exceeds minSpace.
695     */
696    size_type idealSpace = 0; ///< if allocating anyway, provide this much space
697    size_type minSpace = 0; ///< allocate [at least this much] if spaceSize() is smaller
698    size_type maxCapacity = SBuf::maxSize; ///< do not allocate more than this
699    bool allowShared = true; ///< whether sharing our storage with others is OK
700};
701
702/// ostream output operator
703inline std::ostream &
704operator <<(std::ostream& os, const SBuf& S)
705{
706    return S.print(os);
707}
708
709/// Returns a lower-cased copy of its parameter.
710inline SBuf
711ToUpper(SBuf buf)
712{
713    buf.toUpper();
714    return buf;
715}
716
717/// Returns an upper-cased copy of its parameter.
718inline SBuf
719ToLower(SBuf buf)
720{
721    buf.toLower();
722    return buf;
723}
724
725/**
726 * Copy an SBuf into a C-string.
727 *
728 * Guarantees that the output is a c-string of length
729 * no more than SBuf::length()+1 by appending a \0 byte
730 * to the C-string copy of the SBuf contents.
731 *
732 * \note The destination c-string memory MUST be of at least
733 *       length()+1 bytes.
734 *
735 * No protection is added to prevent \0 bytes within the string.
736 * Unexpectedly short strings are a problem for the receiver
737 * to deal with if it cares.
738 *
739 * Unlike SBuf::c_str() does not alter the SBuf in any way.
740 */
741inline void
742SBufToCstring(char *d, const SBuf &s)
743{
744    s.copy(d, s.length());
745    d[s.length()] = '\0'; // 0-terminate the destination
746    debugs(1, DBG_DATA, "built c-string '" << d << "' from " << s);
747}
748
749/**
750 * Copy an SBuf into a C-string.
751 *
752 * \see SBufToCstring(char *d, const SBuf &s)
753 *
754 * \returns A dynamically allocated c-string based on SBuf.
755 *          Use xfree() / safe_free() to release the c-string.
756 */
757inline char *
758SBufToCstring(const SBuf &s)
759{
760    char *d = static_cast<char*>(xmalloc(s.length()+1));
761    SBufToCstring(d, s);
762    return d;
763}
764
765inline
766SBufIterator::SBufIterator(const SBuf &s, size_type pos)
767    : iter(s.rawContent()+pos)
768{}
769
770inline bool
771SBufIterator::operator==(const SBufIterator &s) const
772{
773    // note: maybe the sbuf comparison is unnecessary?
774    return iter == s.iter;
775}
776
777inline bool
778SBufIterator::operator!=(const SBufIterator &s) const
779{
780    // note: maybe the sbuf comparison is unnecessary?
781    return iter != s.iter;
782}
783
784#endif /* SQUID_SBUF_H */
785
Note: See TracBrowser for help on using the repository browser.