Squid Web Cache master
Loading...
Searching...
No Matches
SBuf.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2025 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_SRC_SBUF_SBUF_H
12#define SQUID_SRC_SBUF_SBUF_H
13
14#include "base/InstanceId.h"
15#include "base/TextException.h"
16#include "debug/Stream.h"
17#include "globals.h"
18#include "sbuf/forward.h"
19#include "sbuf/MemBlob.h"
20#include "sbuf/Stats.h"
21
22#include <climits>
23#include <iosfwd>
24#include <iterator>
25#if HAVE_UNISTD_H
26#include <unistd.h>
27#endif
28
29/* SBuf placeholder for printf */
30#ifndef SQUIDSBUFPH
31#define SQUIDSBUFPH "%.*s"
32#define SQUIDSBUFPRINT(s) (s).plength(),(s).rawContent()
33#endif /* SQUIDSBUFPH */
34
35// TODO: move within SBuf and rename
40
41class CharacterSet;
42
49{
50public:
51 // iterator traits
52 using iterator_category = std::input_iterator_tag;
53 using value_type = char;
54 using difference_type = std::ptrdiff_t;
55 using pointer = char*;
56 using reference = char&;
57
58 friend class SBuf;
60 bool operator==(const SBufIterator &s) const;
61 bool operator!=(const SBufIterator &s) const;
62
63 const char &operator*() const { return *iter; }
64 SBufIterator& operator++() { ++iter; return *this; }
65
66protected:
67 SBufIterator(const SBuf &, size_type);
68
69 const char *iter = nullptr;
70};
71
78{
79 friend class SBuf;
80public:
81 SBufReverseIterator& operator++() { --iter; return *this;}
82 const char &operator*() const { return *(iter-1); }
83protected:
85};
86
93class SBuf
94{
95public:
99 using value_type = char;
100 static const size_type npos = 0xffffffff; // max(uint32_t)
101
103 static const size_type maxSize = 0xfffffff;
104
106 SBuf();
107 SBuf(const SBuf &S);
108 SBuf(SBuf&& S) : store_(std::move(S.store_)), off_(S.off_), len_(S.len_) {
109 ++stats.moves;
110 S.store_ = nullptr; //RefCount supports nullptr, and S is about to be destructed
111 S.off_ = S.len_ = 0;
112 }
113
124 explicit SBuf(const char *S, size_type n);
125 explicit SBuf(const char *S);
126
128 explicit SBuf(const std::string &s);
129
130 ~SBuf();
131
136 SBuf& assign(const SBuf &S);
137
142 SBuf& operator =(const SBuf & S) {return assign(S);}
144 ++stats.moves;
145 if (this != &S) {
146 store_ = std::move(S.store_);
147 off_ = S.off_;
148 len_ = S.len_;
149 S.store_ = nullptr; //RefCount supports NULL, and S is about to be destructed
150 S.off_ = 0;
151 S.len_ = 0;
152 }
153 return *this;
154 }
155
156 // XXX: assign(s,n)/append(s,n) calls do not assign or append a c-string as
157 // documented -- they do not stop at the first NUL character! They assign or
158 // append the entire raw memory area, including any embedded NUL characters.
159
170 SBuf& assign(const char *S, size_type n);
171 SBuf& assign(const char *S) {return assign(S,npos);}
172
179 SBuf& operator =(const char *S) {return assign(S);}
180
185 void clear();
186
191 SBuf& append(const SBuf & S);
192
194 SBuf& append(const char c) { push_back(c); return *this; }
195
197 void push_back(char);
198
211 SBuf& append(const char * S, size_type Ssize);
212 SBuf& append(const char * S) { return append(S,npos); }
213
218 SBuf& Printf(const char *fmt, ...) PRINTF_FORMAT_ARG2;
219
224 SBuf& appendf(const char *fmt, ...) PRINTF_FORMAT_ARG2;
225
230 SBuf& vappendf(const char *fmt, va_list vargs);
231
233 std::ostream& print(std::ostream &os) const;
234
240 std::ostream& dump(std::ostream &os) const;
241
246 char operator [](size_type pos) const {++stats.getChar; return store_->mem[off_+pos];}
247
253 char at(size_type pos) const {checkAccessBounds(pos); return operator[](pos);}
254
263 void setAt(size_type pos, char toset);
264
273 int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive, const size_type n) const;
274 int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive) const {
275 return compare(S, isCaseSensitive, npos);
276 }
277
279 inline int cmp(const SBuf &S, const size_type n) const {
280 return compare(S,caseSensitive,n);
281 }
282 inline int cmp(const SBuf &S) const {
283 return compare(S,caseSensitive,npos);
284 }
285
287 inline int caseCmp(const SBuf &S, const size_type n) const {
288 return compare(S,caseInsensitive,n);
289 }
290 inline int caseCmp(const SBuf &S) const {
291 return compare(S,caseInsensitive,npos);
292 }
293
295 int compare(const char *s, const SBufCaseSensitive isCaseSensitive, const size_type n) const;
296 int compare(const char *s, const SBufCaseSensitive isCaseSensitive) const {
297 return compare(s,isCaseSensitive,npos);
298 }
299
301 inline int cmp(const char *S, const size_type n) const {
302 return compare(S,caseSensitive,n);
303 }
304 inline int cmp(const char *S) const {
305 return compare(S,caseSensitive,npos);
306 }
307
309 inline int caseCmp(const char *S, const size_type n) const {
310 return compare(S,caseInsensitive,n);
311 }
312 inline int caseCmp(const char *S) const {
313 return compare(S,caseInsensitive,npos);
314 }
315
321 bool startsWith(const SBuf &S, const SBufCaseSensitive isCaseSensitive = caseSensitive) const;
322
323 bool operator ==(const SBuf & S) const;
324 bool operator !=(const SBuf & S) const;
325 bool operator <(const SBuf &S) const {return (cmp(S) < 0);}
326 bool operator >(const SBuf &S) const {return (cmp(S) > 0);}
327 bool operator <=(const SBuf &S) const {return (cmp(S) <= 0);}
328 bool operator >=(const SBuf &S) const {return (cmp(S) >= 0);}
329
340
342 static const SBufStats& GetStats();
343
350 size_type copy(char *dest, size_type n) const;
351
377 const char* rawContent() const;
378
383 char *rawAppendStart(size_type anticipatedSize);
384
390 void rawAppendFinish(const char *start, size_type actualSize);
391
397 size_type spaceSize() const { return store_->spaceSize(); }
398
416 const char* c_str();
417
419 size_type length() const {return len_;}
420
426 int plength() const {
427 Must(length() <= INT_MAX);
428 return static_cast<int>(length());
429 }
430
435 bool isEmpty() const {return (len_==0);}
436
444 void reserveSpace(size_type minSpace) {
445 Must(minSpace <= maxSize);
446 Must(length() <= maxSize - minSpace);
447 reserveCapacity(length()+minSpace);
448 }
449
458 void reserveCapacity(size_type minCapacity);
459
464 size_type reserve(const SBufReservationRequirements &requirements);
465
480 SBuf& chop(size_type pos, size_type n = npos);
481
489 SBuf& trim(const SBuf &toRemove, bool atBeginning = true, bool atEnd = true);
490
497 SBuf substr(size_type pos, size_type n = npos) const;
498
507 size_type find(char c, size_type startPos = 0) const;
508
517 size_type find(const SBuf & str, size_type startPos = 0) const;
518
526 size_type rfind(char c, size_type endPos = npos) const;
527
536 size_type rfind(const SBuf &str, size_type endPos = npos) const;
537
548 size_type findFirstOf(const CharacterSet &set, size_type startPos = 0) const;
549
558 size_type findLastOf(const CharacterSet &set, size_type endPos = npos) const;
559
568 size_type findFirstNotOf(const CharacterSet &set, size_type startPos = 0) const;
569
576 size_type findLastNotOf(const CharacterSet &set, size_type endPos = npos) const;
577
579 void toLower();
580
582 void toUpper();
583
585 std::string toStdString() const { return std::string(buf(),length()); }
586
588 return const_iterator(*this, 0);
589 }
590
592 return const_iterator(*this, length());
593 }
594
596 return const_reverse_iterator(*this, length());
597 }
598
600 return const_reverse_iterator(*this, 0);
601 }
602
603 // TODO: possibly implement erase() similar to std::string's erase
604 // TODO: possibly implement a replace() call
605
609
610private:
611
619 class Locker
620 {
621 public:
622 Locker(SBuf *parent, const char *otherBuffer) {
623 // lock if otherBuffer intersects the parents buffer area
624 const MemBlob *blob = parent->store_.getRaw();
625 if (blob->mem <= otherBuffer && otherBuffer < (blob->mem + blob->capacity))
626 locket = blob;
627 }
628 private:
630 };
631 friend class Locker;
632
637
644
649 char * buf() const {return (store_->mem+off_);}
650
656 char * bufEnd() const {return (store_->mem+off_+len_);}
657
662 size_type estimateCapacity(size_type desired) const {return (2*desired);}
663
664 void reAlloc(size_type newsize);
665
666 void cow(size_type minsize = npos);
667
668 void checkAccessBounds(const size_type pos) const { Must(pos < length()); }
669
687 char *rawSpace(size_type minSize);
688
696 SBuf& lowAppend(const char * memArea, size_type areaSize);
697};
698
701{
702public:
704
705 /*
706 * Parameters are listed in the reverse order of importance: Satisfaction of
707 * the lower-listed requirements may violate the higher-listed requirements.
708 * For example, idealSpace has no effect unless it exceeds minSpace.
709 */
713 bool allowShared = true;
714};
715
717inline std::ostream &
718operator <<(std::ostream& os, const SBuf& S)
719{
720 return S.print(os);
721}
722
724inline SBuf
726{
727 buf.toUpper();
728 return buf;
729}
730
732inline SBuf
734{
735 buf.toLower();
736 return buf;
737}
738
755inline void
756SBufToCstring(char *d, const SBuf &s)
757{
758 s.copy(d, s.length());
759 d[s.length()] = '\0'; // 0-terminate the destination
760 debugs(1, DBG_DATA, "built c-string '" << d << "' from " << s);
761}
762
771inline char *
773{
774 char *d = static_cast<char*>(xmalloc(s.length()+1));
775 SBufToCstring(d, s);
776 return d;
777}
778
779inline
781 : iter(s.rawContent()+pos)
782{}
783
784inline bool
786{
787 // note: maybe the sbuf comparison is unnecessary?
788 return iter == s.iter;
789}
790
791inline bool
793{
794 // note: maybe the sbuf comparison is unnecessary?
795 return iter != s.iter;
796}
797
798#endif /* SQUID_SRC_SBUF_SBUF_H */
799
SBuf ToUpper(SBuf buf)
Returns a lower-cased copy of its parameter.
Definition SBuf.h:725
std::ostream & operator<<(std::ostream &os, const SBuf &S)
ostream output operator
Definition SBuf.h:718
SBufCaseSensitive
Definition SBuf.h:36
@ caseInsensitive
Definition SBuf.h:38
@ caseSensitive
Definition SBuf.h:37
void SBufToCstring(char *d, const SBuf &s)
Definition SBuf.h:756
SBuf ToLower(SBuf buf)
Returns an upper-cased copy of its parameter.
Definition SBuf.h:733
#define Must(condition)
optimized set of C chars, with quick membership test and merge support
size_type spaceSize() const
the number unused bytes at the end of the allocated blob
Definition MemBlob.h:66
value_type * mem
raw allocated memory block
Definition MemBlob.h:113
uint32_t size_type
Definition MemBlob.h:52
size_type capacity
size of the raw allocated memory block
Definition MemBlob.h:114
C * getRaw() const
Definition RefCount.h:89
MemBlob::size_type size_type
Definition SBuf.h:59
bool operator!=(const SBufIterator &s) const
Definition SBuf.h:792
char & reference
Definition SBuf.h:56
bool operator==(const SBufIterator &s) const
Definition SBuf.h:785
char value_type
Definition SBuf.h:53
const char * iter
Definition SBuf.h:69
std::ptrdiff_t difference_type
Definition SBuf.h:54
std::input_iterator_tag iterator_category
Definition SBuf.h:52
char * pointer
Definition SBuf.h:55
const char & operator*() const
Definition SBuf.h:63
SBufIterator & operator++()
Definition SBuf.h:64
SBufIterator(const SBuf &, size_type)
Definition SBuf.h:780
Named SBuf::reserve() parameters. Defaults ask for and restrict nothing.
Definition SBuf.h:701
bool allowShared
whether sharing our storage with others is OK
Definition SBuf.h:713
size_type minSpace
allocate [at least this much] if spaceSize() is smaller
Definition SBuf.h:711
SBuf::size_type size_type
Definition SBuf.h:703
size_type maxCapacity
do not allocate more than this
Definition SBuf.h:712
size_type idealSpace
if allocating anyway, provide this much space
Definition SBuf.h:710
SBufReverseIterator & operator++()
Definition SBuf.h:81
SBufReverseIterator(const SBuf &s, size_type sz)
Definition SBuf.h:84
const char & operator*() const
Definition SBuf.h:82
uint64_t moves
number of move constructions/assignments
Definition Stats.h:42
uint64_t getChar
number of calls to at() and operator[]
Definition Stats.h:45
Locker(SBuf *parent, const char *otherBuffer)
Definition SBuf.h:622
MemBlob::Pointer locket
Definition SBuf.h:629
Definition SBuf.h:94
char * rawAppendStart(size_type anticipatedSize)
Definition SBuf.cc:136
void toUpper()
converts all characters to upper case;
Definition SBuf.cc:824
int cmp(const char *S) const
Definition SBuf.h:304
void push_back(char)
Append a single character. The character may be NUL (\0).
Definition SBuf.cc:208
int caseCmp(const SBuf &S, const size_type n) const
shorthand version for case-insensitive compare()
Definition SBuf.h:287
SBuf & append(const char c)
Append a single character. The character may be NUL (\0).
Definition SBuf.h:194
SBuf & assign(const char *S)
Definition SBuf.h:171
int cmp(const char *S, const size_type n) const
Shorthand version for C-string compare().
Definition SBuf.h:301
SBuf(SBuf &&S)
Definition SBuf.h:108
const char * rawContent() const
Definition SBuf.cc:509
static const size_type npos
Definition SBuf.h:100
bool operator<(const SBuf &S) const
Definition SBuf.h:325
char at(size_type pos) const
Definition SBuf.h:253
SBuf & append(const char *S)
Definition SBuf.h:212
SBuf consume(size_type n=npos)
Definition SBuf.cc:481
SBuf & vappendf(const char *fmt, va_list vargs)
Definition SBuf.cc:239
const char * c_str()
Definition SBuf.cc:516
~SBuf()
Definition SBuf.cc:68
SBuf & chop(size_type pos, size_type n=npos)
Definition SBuf.cc:530
void reserveCapacity(size_type minCapacity)
Definition SBuf.cc:105
size_type len_
number of our content bytes in shared store_
Definition SBuf.h:635
static const SBufStats & GetStats()
gets global statistic information
Definition SBuf.cc:494
static MemBlob::Pointer GetStorePrototype()
Definition SBuf.cc:76
SBuf & lowAppend(const char *memArea, size_type areaSize)
Definition SBuf.cc:863
const InstanceId< SBuf > id
Definition SBuf.h:608
void reAlloc(size_type newsize)
Definition SBuf.cc:845
char * buf() const
Definition SBuf.h:649
size_type length() const
Returns the number of bytes stored in SBuf.
Definition SBuf.h:419
static SBufStats stats
class-wide statistics
Definition SBuf.h:636
SBuf & appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Definition SBuf.cc:229
SBuf()
create an empty (zero-size) SBuf
Definition SBuf.cc:28
size_type rfind(char c, size_type endPos=npos) const
Definition SBuf.cc:692
SBuf & operator=(const SBuf &S)
Definition SBuf.h:142
size_type reserve(const SBufReservationRequirements &requirements)
Definition SBuf.cc:112
SBuf & Printf(const char *fmt,...) PRINTF_FORMAT_ARG2
Definition SBuf.cc:214
int cmp(const SBuf &S, const size_type n) const
shorthand version for compare()
Definition SBuf.h:279
size_type findFirstNotOf(const CharacterSet &set, size_type startPos=0) const
Definition SBuf.cc:746
int plength() const
Definition SBuf.h:426
SBuf & trim(const SBuf &toRemove, bool atBeginning=true, bool atEnd=true)
Definition SBuf.cc:551
bool operator>=(const SBuf &S) const
Definition SBuf.h:328
int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive) const
Definition SBuf.h:274
size_type spaceSize() const
Definition SBuf.h:397
size_type find(char c, size_type startPos=0) const
Definition SBuf.cc:584
int cmp(const SBuf &S) const
Definition SBuf.h:282
size_type findFirstOf(const CharacterSet &set, size_type startPos=0) const
Definition SBuf.cc:723
bool operator!=(const SBuf &S) const
Definition SBuf.cc:475
size_type copy(char *dest, size_type n) const
Definition SBuf.cc:500
std::string toStdString() const
std::string export function
Definition SBuf.h:585
bool isEmpty() const
Definition SBuf.h:435
bool operator==(const SBuf &S) const
Definition SBuf.cc:455
size_type estimateCapacity(size_type desired) const
Definition SBuf.h:662
size_type findLastNotOf(const CharacterSet &set, size_type endPos=npos) const
Definition SBuf.cc:790
char * rawSpace(size_type minSize)
Definition SBuf.cc:157
bool operator>(const SBuf &S) const
Definition SBuf.h:326
const_iterator begin() const
Definition SBuf.h:587
char operator[](size_type pos) const
Definition SBuf.h:246
std::ostream & dump(std::ostream &os) const
Definition SBuf.cc:303
void cow(size_type minsize=npos)
Definition SBuf.cc:878
void checkAccessBounds(const size_type pos) const
Definition SBuf.h:668
SBuf & append(const SBuf &S)
Definition SBuf.cc:185
char value_type
Definition SBuf.h:99
MemBlob::Pointer store_
memory block, possibly shared with other SBufs
Definition SBuf.h:633
const_reverse_iterator rbegin() const
Definition SBuf.h:595
SBufIterator const_iterator
Definition SBuf.h:97
SBufReverseIterator const_reverse_iterator
Definition SBuf.h:98
int caseCmp(const SBuf &S) const
Definition SBuf.h:290
int caseCmp(const char *S, const size_type n) const
Shorthand version for case-insensitive C-string compare().
Definition SBuf.h:309
void reserveSpace(size_type minSpace)
Definition SBuf.h:444
int caseCmp(const char *S) const
Definition SBuf.h:312
int compare(const char *s, const SBufCaseSensitive isCaseSensitive) const
Definition SBuf.h:296
size_type findLastOf(const CharacterSet &set, size_type endPos=npos) const
Definition SBuf.cc:769
size_type off_
our content start offset from the beginning of shared store_
Definition SBuf.h:634
const_iterator end() const
Definition SBuf.h:591
bool startsWith(const SBuf &S, const SBufCaseSensitive isCaseSensitive=caseSensitive) const
Definition SBuf.cc:442
void clear()
Definition SBuf.cc:175
SBuf substr(size_type pos, size_type n=npos) const
Definition SBuf.cc:576
std::ostream & print(std::ostream &os) const
print the SBuf contents to the supplied ostream
Definition SBuf.cc:295
MemBlob::size_type size_type
Definition SBuf.h:96
void rawAppendFinish(const char *start, size_type actualSize)
Definition SBuf.cc:144
SBuf & assign(const SBuf &S)
Definition SBuf.cc:83
bool operator<=(const SBuf &S) const
Definition SBuf.h:327
const_reverse_iterator rend() const
Definition SBuf.h:599
void setAt(size_type pos, char toset)
Definition SBuf.cc:328
void toLower()
converts all characters to lower case;
Definition SBuf.cc:811
int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive, const size_type n) const
Definition SBuf.cc:352
char * bufEnd() const
Definition SBuf.h:656
static const size_type maxSize
Maximum size of a SBuf. By design it MUST be < MAX(size_type)/2. Currently 256Mb.
Definition SBuf.h:103
#define PRINTF_FORMAT_ARG2
#define DBG_DATA
Definition Stream.h:40
#define debugs(SECTION, LEVEL, CONTENT)
Definition Stream.h:192
STL namespace.
#define xmalloc
#define INT_MAX
Definition types.h:70