SBuf.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 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
36 typedef enum {
40 
41 class CharacterSet;
42 
49 {
50 public:
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 
66 protected:
67  SBufIterator(const SBuf &, size_type);
68 
69  const char *iter = nullptr;
70 };
71 
78 {
79  friend class SBuf;
80 public:
81  SBufReverseIterator& operator++() { --iter; return *this;}
82  const char &operator*() const { return *(iter-1); }
83 protected:
85 };
86 
93 class SBuf
94 {
95 public:
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 
339  SBuf consume(size_type n = npos);
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 
591  const_iterator end() const {
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 
610 private:
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 
636  static SBufStats stats;
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 {
702 public:
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 
717 inline std::ostream &
718 operator <<(std::ostream& os, const SBuf& S)
719 {
720  return S.print(os);
721 }
722 
724 inline SBuf
726 {
727  buf.toUpper();
728  return buf;
729 }
730 
732 inline SBuf
734 {
735  buf.toLower();
736  return buf;
737 }
738 
755 inline void
756 SBufToCstring(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 
771 inline char *
773 {
774  char *d = static_cast<char*>(xmalloc(s.length()+1));
775  SBufToCstring(d, s);
776  return d;
777 }
778 
779 inline
781  : iter(s.rawContent()+pos)
782 {}
783 
784 inline bool
786 {
787  // note: maybe the sbuf comparison is unnecessary?
788  return iter == s.iter;
789 }
790 
791 inline 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 
const char * iter
Definition: SBuf.h:69
char * pointer
Definition: SBuf.h:55
size_type find(char c, size_type startPos=0) const
Definition: SBuf.cc:584
void push_back(char)
Append a single character. The character may be NUL (\0).
Definition: SBuf.cc:208
SBuf(SBuf &&S)
Definition: SBuf.h:108
size_type idealSpace
if allocating anyway, provide this much space
Definition: SBuf.h:710
SBuf & assign(const SBuf &S)
Definition: SBuf.cc:83
bool operator!=(const SBufIterator &s) const
Definition: SBuf.h:792
#define xmalloc
const_reverse_iterator rbegin() const
Definition: SBuf.h:595
bool operator>=(const SBuf &S) const
Definition: SBuf.h:328
@ caseSensitive
Definition: SBuf.h:37
SBuf & append(const char *S)
Definition: SBuf.h:212
std::input_iterator_tag iterator_category
Definition: SBuf.h:52
char value_type
Definition: SBuf.h:53
bool isEmpty() const
Definition: SBuf.h:435
std::ostream & operator<<(std::ostream &os, const SBuf &S)
ostream output operator
Definition: SBuf.h:718
char value_type
Definition: SBuf.h:99
size_type len_
number of our content bytes in shared store_
Definition: SBuf.h:635
SBufReverseIterator const_reverse_iterator
Definition: SBuf.h:98
void checkAccessBounds(const size_type pos) const
Definition: SBuf.h:668
bool operator==(const SBufIterator &s) const
Definition: SBuf.h:785
void reserveSpace(size_type minSpace)
Definition: SBuf.h:444
size_type estimateCapacity(size_type desired) const
Definition: SBuf.h:662
static MemBlob::Pointer GetStorePrototype()
Definition: SBuf.cc:76
SBuf & append(const char c)
Append a single character. The character may be NUL (\0).
Definition: SBuf.h:194
SBuf & lowAppend(const char *memArea, size_type areaSize)
Definition: SBuf.cc:863
size_type spaceSize() const
the number unused bytes at the end of the allocated blob
Definition: MemBlob.h:63
SBuf & vappendf(const char *fmt, va_list vargs)
Definition: SBuf.cc:239
size_type maxCapacity
do not allocate more than this
Definition: SBuf.h:712
SBuf::size_type size_type
Definition: SBuf.h:703
int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive, const size_type n) const
Definition: SBuf.cc:352
int cmp(const char *S) const
Definition: SBuf.h:304
Definition: SBuf.h:93
int cmp(const char *S, const size_type n) const
Shorthand version for C-string compare().
Definition: SBuf.h:301
void SBufToCstring(char *d, const SBuf &s)
Definition: SBuf.h:756
Named SBuf::reserve() parameters. Defaults ask for and restrict nothing.
Definition: SBuf.h:700
void rawAppendFinish(const char *start, size_type actualSize)
Definition: SBuf.cc:144
bool operator==(const SBuf &S) const
Definition: SBuf.cc:455
int caseCmp(const char *S) const
Definition: SBuf.h:312
char * bufEnd() const
Definition: SBuf.h:656
char * rawSpace(size_type minSize)
Definition: SBuf.cc:157
C * getRaw() const
Definition: RefCount.h:89
size_type spaceSize() const
Definition: SBuf.h:397
void toLower()
converts all characters to lower case;
Definition: SBuf.cc:811
bool startsWith(const SBuf &S, const SBufCaseSensitive isCaseSensitive=caseSensitive) const
Definition: SBuf.cc:442
SBufCaseSensitive
Definition: SBuf.h:36
bool allowShared
whether sharing our storage with others is OK
Definition: SBuf.h:713
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
int caseCmp(const SBuf &S) const
Definition: SBuf.h:290
SBuf substr(size_type pos, size_type n=npos) const
Definition: SBuf.cc:576
Locker(SBuf *parent, const char *otherBuffer)
Definition: SBuf.h:622
void clear()
Definition: SBuf.cc:175
#define PRINTF_FORMAT_ARG2
size_type reserve(const SBufReservationRequirements &requirements)
Definition: SBuf.cc:112
int caseCmp(const char *S, const size_type n) const
Shorthand version for case-insensitive C-string compare().
Definition: SBuf.h:309
#define DBG_DATA
Definition: Stream.h:40
SBuf & chop(size_type pos, size_type n=npos)
Definition: SBuf.cc:530
char * rawAppendStart(size_type anticipatedSize)
Definition: SBuf.cc:136
size_type rfind(char c, size_type endPos=npos) const
Definition: SBuf.cc:692
void toUpper()
converts all characters to upper case;
Definition: SBuf.cc:824
const_reverse_iterator rend() const
Definition: SBuf.h:599
bool operator>(const SBuf &S) const
Definition: SBuf.h:326
const char * rawContent() const
Definition: SBuf.cc:509
SBuf consume(size_type n=npos)
Definition: SBuf.cc:481
@ caseInsensitive
Definition: SBuf.h:38
MemBlob::Pointer locket
Definition: SBuf.h:629
const_iterator end() const
Definition: SBuf.h:591
MemBlob::size_type size_type
Definition: SBuf.h:96
std::ptrdiff_t difference_type
Definition: SBuf.h:54
std::ostream & dump(std::ostream &os) const
Definition: SBuf.cc:303
#define INT_MAX
Definition: types.h:70
char at(size_type pos) const
Definition: SBuf.h:253
SBuf & Printf(const char *fmt,...) PRINTF_FORMAT_ARG2
Definition: SBuf.cc:214
SBuf()
create an empty (zero-size) SBuf
Definition: SBuf.cc:28
char & reference
Definition: SBuf.h:56
SBuf ToUpper(SBuf buf)
Returns a lower-cased copy of its parameter.
Definition: SBuf.h:725
SBufReverseIterator(const SBuf &s, size_type sz)
Definition: SBuf.h:84
const char & operator*() const
Definition: SBuf.h:63
const_iterator begin() const
Definition: SBuf.h:587
const char & operator*() const
Definition: SBuf.h:82
std::string toStdString() const
std::string export function
Definition: SBuf.h:585
bool operator<(const SBuf &S) const
Definition: SBuf.h:325
std::ostream & print(std::ostream &os) const
print the SBuf contents to the supplied ostream
Definition: SBuf.cc:295
SBufIterator & operator++()
Definition: SBuf.h:64
void cow(size_type minsize=npos)
Definition: SBuf.cc:878
~SBuf()
Definition: SBuf.cc:68
SBuf & trim(const SBuf &toRemove, bool atBeginning=true, bool atEnd=true)
Definition: SBuf.cc:551
bool operator<=(const SBuf &S) const
Definition: SBuf.h:327
const char * c_str()
Definition: SBuf.cc:516
size_type length() const
Returns the number of bytes stored in SBuf.
Definition: SBuf.h:419
size_type off_
our content start offset from the beginning of shared store_
Definition: SBuf.h:634
int plength() const
Definition: SBuf.h:426
static SBufStats stats
class-wide statistics
Definition: SBuf.h:636
SBuf & append(const SBuf &S)
Definition: SBuf.cc:185
size_type findLastOf(const CharacterSet &set, size_type endPos=npos) const
Definition: SBuf.cc:769
static const size_type npos
Definition: SBuf.h:100
size_type findFirstNotOf(const CharacterSet &set, size_type startPos=0) const
Definition: SBuf.cc:746
size_type minSpace
allocate [at least this much] if spaceSize() is smaller
Definition: SBuf.h:711
void setAt(size_type pos, char toset)
Definition: SBuf.cc:328
SBufReverseIterator & operator++()
Definition: SBuf.h:81
SBuf & operator=(const SBuf &S)
Definition: SBuf.h:142
uint32_t size_type
Definition: MemBlob.h:49
MemBlob::Pointer store_
memory block, possibly shared with other SBufs
Definition: SBuf.h:633
size_type capacity
size of the raw allocated memory block
Definition: MemBlob.h:111
char * buf() const
Definition: SBuf.h:649
int cmp(const SBuf &S) const
Definition: SBuf.h:282
void reserveCapacity(size_type minCapacity)
Definition: SBuf.cc:105
int cmp(const SBuf &S, const size_type n) const
shorthand version for compare()
Definition: SBuf.h:279
static const SBufStats & GetStats()
gets global statistic information
Definition: SBuf.cc:494
void reAlloc(size_type newsize)
Definition: SBuf.cc:845
MemBlob::size_type size_type
Definition: SBuf.h:59
#define Must(condition)
Definition: TextException.h:75
bool operator!=(const SBuf &S) const
Definition: SBuf.cc:475
SBuf ToLower(SBuf buf)
Returns an upper-cased copy of its parameter.
Definition: SBuf.h:733
size_type findLastNotOf(const CharacterSet &set, size_type endPos=npos) const
Definition: SBuf.cc:790
optimized set of C chars, with quick membership test and merge support
Definition: CharacterSet.h:17
int caseCmp(const SBuf &S, const size_type n) const
shorthand version for case-insensitive compare()
Definition: SBuf.h:287
SBufIterator(const SBuf &, size_type)
Definition: SBuf.h:780
SBuf & appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Definition: SBuf.cc:229
char operator[](size_type pos) const
Definition: SBuf.h:246
const InstanceId< SBuf > id
Definition: SBuf.h:608
int compare(const char *s, const SBufCaseSensitive isCaseSensitive) const
Definition: SBuf.h:296
size_type findFirstOf(const CharacterSet &set, size_type startPos=0) const
Definition: SBuf.cc:723
char * mem
raw allocated memory block
Definition: MemBlob.h:110
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive) const
Definition: SBuf.h:274
SBufIterator const_iterator
Definition: SBuf.h:97
uint64_t getChar
number of calls to at() and operator[]
Definition: Stats.h:45
size_type copy(char *dest, size_type n) const
Definition: SBuf.cc:500
SBuf & assign(const char *S)
Definition: SBuf.h:171
uint64_t moves
number of move constructions/assignments
Definition: Stats.h:42

 

Introduction

Documentation

Support

Miscellaneous