SBuf.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2018 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 "base/TextException.h"
16 #include "Debug.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 
48 class SBufIterator : public std::iterator<std::input_iterator_tag, char>
49 {
50 public:
51  friend class SBuf;
53  bool operator==(const SBufIterator &s) const;
54  bool operator!=(const SBufIterator &s) const;
55 
56  const char &operator*() const { return *iter; }
57  SBufIterator& operator++() { ++iter; return *this; }
58 
59 protected:
60  SBufIterator(const SBuf &, size_type);
61 
62  const char *iter = nullptr;
63 };
64 
71 {
72  friend class SBuf;
73 public:
74  SBufReverseIterator& operator++() { --iter; return *this;}
75  const char &operator*() const { return *(iter-1); }
76 protected:
78 };
79 
86 class SBuf
87 {
88 public:
92  static const size_type npos = 0xffffffff; // max(uint32_t)
93 
95  static const size_type maxSize = 0xfffffff;
96 
98  SBuf();
99  SBuf(const SBuf &S);
100  SBuf(SBuf&& S) : store_(std::move(S.store_)), off_(S.off_), len_(S.len_) {
101  ++stats.moves;
102  S.store_ = nullptr; //RefCount supports nullptr, and S is about to be destructed
103  S.off_ = S.len_ = 0;
104  }
105 
116  explicit SBuf(const char *S, size_type n);
117  explicit SBuf(const char *S);
118 
120  explicit SBuf(const std::string &s);
121 
122  ~SBuf();
123 
128  SBuf& assign(const SBuf &S);
129 
134  SBuf& operator =(const SBuf & S) {return assign(S);}
136  ++stats.moves;
137  if (this != &S) {
138  store_ = std::move(S.store_);
139  off_ = S.off_;
140  len_ = S.len_;
141  S.store_ = NULL; //RefCount supports NULL, and S is about to be destructed
142  S.off_ = 0;
143  S.len_ = 0;
144  }
145  return *this;
146  }
147 
158  SBuf& assign(const char *S, size_type n);
159  SBuf& assign(const char *S) {return assign(S,npos);}
160 
167  SBuf& operator =(const char *S) {return assign(S);}
168 
173  void clear();
174 
179  SBuf& append(const SBuf & S);
180 
182  SBuf& append(const char c);
183 
196  SBuf& append(const char * S, size_type Ssize);
197  SBuf& append(const char * S) { return append(S,npos); }
198 
203  SBuf& Printf(const char *fmt, ...);
204 
209  SBuf& appendf(const char *fmt, ...);
210 
215  SBuf& vappendf(const char *fmt, va_list vargs);
216 
218  std::ostream& print(std::ostream &os) const;
219 
225  std::ostream& dump(std::ostream &os) const;
226 
231  char operator [](size_type pos) const {++stats.getChar; return store_->mem[off_+pos];}
232 
238  char at(size_type pos) const {checkAccessBounds(pos); return operator[](pos);}
239 
248  void setAt(size_type pos, char toset);
249 
258  int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive, const size_type n) const;
259  int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive) const {
260  return compare(S, isCaseSensitive, npos);
261  }
262 
264  inline int cmp(const SBuf &S, const size_type n) const {
265  return compare(S,caseSensitive,n);
266  }
267  inline int cmp(const SBuf &S) const {
268  return compare(S,caseSensitive,npos);
269  }
270 
272  inline int caseCmp(const SBuf &S, const size_type n) const {
273  return compare(S,caseInsensitive,n);
274  }
275  inline int caseCmp(const SBuf &S) const {
276  return compare(S,caseInsensitive,npos);
277  }
278 
280  int compare(const char *s, const SBufCaseSensitive isCaseSensitive, const size_type n) const;
281  int compare(const char *s, const SBufCaseSensitive isCaseSensitive) const {
282  return compare(s,isCaseSensitive,npos);
283  }
284 
286  inline int cmp(const char *S, const size_type n) const {
287  return compare(S,caseSensitive,n);
288  }
289  inline int cmp(const char *S) const {
290  return compare(S,caseSensitive,npos);
291  }
292 
294  inline int caseCmp(const char *S, const size_type n) const {
295  return compare(S,caseInsensitive,n);
296  }
297  inline int caseCmp(const char *S) const {
298  return compare(S,caseInsensitive,npos);
299  }
300 
306  bool startsWith(const SBuf &S, const SBufCaseSensitive isCaseSensitive = caseSensitive) const;
307 
308  bool operator ==(const SBuf & S) const;
309  bool operator !=(const SBuf & S) const;
310  bool operator <(const SBuf &S) const {return (cmp(S) < 0);}
311  bool operator >(const SBuf &S) const {return (cmp(S) > 0);}
312  bool operator <=(const SBuf &S) const {return (cmp(S) <= 0);}
313  bool operator >=(const SBuf &S) const {return (cmp(S) >= 0);}
314 
324  SBuf consume(size_type n = npos);
325 
327  static const SBufStats& GetStats();
328 
335  size_type copy(char *dest, size_type n) const;
336 
362  const char* rawContent() const;
363 
368  char *rawAppendStart(size_type anticipatedSize);
369 
375  void rawAppendFinish(const char *start, size_type actualSize);
376 
382  size_type spaceSize() const { return store_->spaceSize(); }
383 
401  const char* c_str();
402 
404  size_type length() const {return len_;}
405 
411  int plength() const {
412  Must(length() <= INT_MAX);
413  return static_cast<int>(length());
414  }
415 
420  bool isEmpty() const {return (len_==0);}
421 
429  void reserveSpace(size_type minSpace) {
430  Must(minSpace <= maxSize);
431  Must(length() <= maxSize - minSpace);
432  reserveCapacity(length()+minSpace);
433  }
434 
443  void reserveCapacity(size_type minCapacity);
444 
449  size_type reserve(const SBufReservationRequirements &requirements);
450 
465  SBuf& chop(size_type pos, size_type n = npos);
466 
474  SBuf& trim(const SBuf &toRemove, bool atBeginning = true, bool atEnd = true);
475 
482  SBuf substr(size_type pos, size_type n = npos) const;
483 
492  size_type find(char c, size_type startPos = 0) const;
493 
502  size_type find(const SBuf & str, size_type startPos = 0) const;
503 
511  size_type rfind(char c, size_type endPos = npos) const;
512 
521  size_type rfind(const SBuf &str, size_type endPos = npos) const;
522 
533  size_type findFirstOf(const CharacterSet &set, size_type startPos = 0) const;
534 
543  size_type findLastOf(const CharacterSet &set, size_type endPos = npos) const;
544 
553  size_type findFirstNotOf(const CharacterSet &set, size_type startPos = 0) const;
554 
561  size_type findLastNotOf(const CharacterSet &set, size_type endPos = npos) const;
562 
564  void toLower();
565 
567  void toUpper();
568 
570  std::string toStdString() const { return std::string(buf(),length()); }
571 
573  return const_iterator(*this, 0);
574  }
575 
576  const_iterator end() const {
577  return const_iterator(*this, length());
578  }
579 
581  return const_reverse_iterator(*this, length());
582  }
583 
585  return const_reverse_iterator(*this, 0);
586  }
587 
588  // TODO: possibly implement erase() similar to std::string's erase
589  // TODO: possibly implement a replace() call
590 
594 
595 private:
596 
604  class Locker
605  {
606  public:
607  Locker(SBuf *parent, const char *otherBuffer) {
608  // lock if otherBuffer intersects the parents buffer area
609  const MemBlob *blob = parent->store_.getRaw();
610  if (blob->mem <= otherBuffer && otherBuffer < (blob->mem + blob->capacity))
611  locket = blob;
612  }
613  private:
615  };
616  friend class Locker;
617 
621  static SBufStats stats;
622 
629 
634  char * buf() const {return (store_->mem+off_);}
635 
641  char * bufEnd() const {return (store_->mem+off_+len_);}
642 
647  size_type estimateCapacity(size_type desired) const {return (2*desired);}
648 
649  void reAlloc(size_type newsize);
650 
651  void cow(size_type minsize = npos);
652 
653  void checkAccessBounds(const size_type pos) const { Must(pos < length()); }
654 
672  char *rawSpace(size_type minSize);
673 
681  SBuf& lowAppend(const char * memArea, size_type areaSize);
682 };
683 
686 {
687 public:
689 
690  /*
691  * Parameters are listed in the reverse order of importance: Satisfaction of
692  * the lower-listed requirements may violate the higher-listed requirements.
693  * For example, idealSpace has no effect unless it exceeds minSpace.
694  */
698  bool allowShared = true;
699 };
700 
702 inline std::ostream &
703 operator <<(std::ostream& os, const SBuf& S)
704 {
705  return S.print(os);
706 }
707 
709 inline SBuf
711 {
712  buf.toUpper();
713  return buf;
714 }
715 
717 inline SBuf
719 {
720  buf.toLower();
721  return buf;
722 }
723 
740 inline void
741 SBufToCstring(char *d, const SBuf &s)
742 {
743  s.copy(d, s.length());
744  d[s.length()] = '\0'; // 0-terminate the destination
745  debugs(1, DBG_DATA, "built c-string '" << d << "' from " << s);
746 }
747 
756 inline char *
758 {
759  char *d = static_cast<char*>(xmalloc(s.length()+1));
760  SBufToCstring(d, s);
761  return d;
762 }
763 
764 inline
766  : iter(s.rawContent()+pos)
767 {}
768 
769 inline bool
771 {
772  // note: maybe the sbuf comparison is unnecessary?
773  return iter == s.iter;
774 }
775 
776 inline bool
778 {
779  // note: maybe the sbuf comparison is unnecessary?
780  return iter != s.iter;
781 }
782 
783 #endif /* SQUID_SBUF_H */
784 
int caseCmp(const SBuf &S, const size_type n) const
shorthand version for case-insensitive compare()
Definition: SBuf.h:272
void reserveSpace(size_type minSpace)
Definition: SBuf.h:429
uint32_t size_type
Definition: MemBlob.h:51
~SBuf()
Definition: SBuf.cc:68
std::ostream & operator<<(std::ostream &o, const allow_t a)
Definition: Acl.h:157
const_iterator end() const
Definition: SBuf.h:576
bool operator==(const SBufIterator &s) const
Definition: SBuf.h:770
bool operator>=(const SBuf &S) const
Definition: SBuf.h:313
std::ostream & dump(std::ostream &os) const
Definition: SBuf.cc:313
SBuf & operator=(const SBuf &S)
Definition: SBuf.h:134
SBuf & appendf(const char *fmt,...)
Definition: SBuf.cc:239
SBufReverseIterator & operator++()
Definition: SBuf.h:74
int caseCmp(const char *S, const size_type n) const
Shorthand version for case-insensitive C-string compare().
Definition: SBuf.h:294
SBuf & assign(const SBuf &S)
Definition: SBuf.cc:83
size_type idealSpace
if allocating anyway, provide this much space
Definition: SBuf.h:695
Definition: SBuf.h:86
SBuf(SBuf &&S)
Definition: SBuf.h:100
bool operator!=(const SBufIterator &s) const
Definition: SBuf.h:777
SBuf & append(const SBuf &S)
Definition: SBuf.cc:195
size_type capacity
size of the raw allocated memory block
Definition: MemBlob.h:103
SBufIterator const_iterator
Definition: SBuf.h:90
static const SBufStats & GetStats()
gets global statistic informations
Definition: SBuf.cc:504
SBuf ToUpper(SBuf buf)
Returns a lower-cased copy of its parameter.
Definition: SBuf.h:710
SBuf & chop(size_type pos, size_type n=npos)
Definition: SBuf.cc:540
std::ostream & print(std::ostream &os) const
print the SBuf contents to the supplied ostream
Definition: SBuf.cc:305
size_type findLastNotOf(const CharacterSet &set, size_type endPos=npos) const
Definition: SBuf.cc:800
void clear()
Definition: SBuf.cc:178
#define Must(condition)
Like assert() but throws an exception instead of aborting the process.
Definition: TextException.h:69
bool operator<(const SBuf &S) const
Definition: SBuf.h:310
const_reverse_iterator rbegin() const
Definition: SBuf.h:580
void toUpper()
converts all characters to upper case;
Definition: SBuf.cc:834
bool isEmpty() const
Definition: SBuf.h:420
MemBlob::Pointer store_
memory block, possibly shared with other SBufs
Definition: SBuf.h:618
SBufReverseIterator const_reverse_iterator
Definition: SBuf.h:91
int plength() const
Definition: SBuf.h:411
void SBufToCstring(char *d, const SBuf &s)
Definition: SBuf.h:741
static const size_type maxSize
Maximum size of a SBuf. By design it MUST be &lt; MAX(size_type)/2. Currently 256Mb. ...
Definition: SBuf.h:95
const char & operator*() const
Definition: SBuf.h:56
void checkAccessBounds(const size_type pos) const
Definition: SBuf.h:653
char operator[](size_type pos) const
Definition: SBuf.h:231
char * buf() const
Definition: SBuf.h:634
void setAt(size_type pos, char toset)
Definition: SBuf.cc:338
static MemBlob::Pointer GetStorePrototype()
Definition: SBuf.cc:76
std::string toStdString() const
std::string export function
Definition: SBuf.h:570
SBuf & lowAppend(const char *memArea, size_type areaSize)
Definition: SBuf.cc:869
void rawAppendFinish(const char *start, size_type actualSize)
Definition: SBuf.cc:144
void reAlloc(size_type newsize)
Definition: SBuf.cc:855
void toLower()
converts all characters to lower case;
Definition: SBuf.cc:821
SBufCaseSensitive
Definition: SBuf.h:36
Named SBuf::reserve() parameters. Defaults ask for and restrict nothing.
Definition: SBuf.h:685
size_type length() const
Returns the number of bytes stored in SBuf.
Definition: SBuf.h:404
SBufReverseIterator(const SBuf &s, size_type sz)
Definition: SBuf.h:77
char * rawAppendStart(size_type anticipatedSize)
Definition: SBuf.cc:136
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:124
size_type maxCapacity
do not allocate more than this
Definition: SBuf.h:697
bool operator!=(const SBuf &S) const
Definition: SBuf.cc:485
SBuf & Printf(const char *fmt,...)
Definition: SBuf.cc:224
int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive) const
Definition: SBuf.h:259
size_type off_
our content start offset from the beginning of shared store_
Definition: SBuf.h:619
char * bufEnd() const
Definition: SBuf.h:641
SBuf & assign(const char *S)
Definition: SBuf.h:159
const char * c_str()
Definition: SBuf.cc:526
optimized set of C chars, with quick membership test and merge support
Definition: CharacterSet.h:17
bool allowShared
whether sharing our storage with others is OK
Definition: SBuf.h:698
int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive, const size_type n) const
Definition: SBuf.cc:362
char * mem
raw allocated memory block
Definition: MemBlob.h:102
int caseCmp(const char *S) const
Definition: SBuf.h:297
SBuf consume(size_type n=npos)
Definition: SBuf.cc:491
char * rawSpace(size_type minSize)
Definition: SBuf.cc:157
void const char * buf
Definition: stub_helper.cc:16
const char & operator*() const
Definition: SBuf.h:75
int cmp(const char *S, const size_type n) const
Shorthand version for C-string compare().
Definition: SBuf.h:286
size_type minSpace
allocate [at least this much] if spaceSize() is smaller
Definition: SBuf.h:696
int cmp(const SBuf &S) const
Definition: SBuf.h:267
SBufIterator & operator++()
Definition: SBuf.h:57
size_type findFirstOf(const CharacterSet &set, size_type startPos=0) const
Definition: SBuf.cc:733
int cmp(const char *S) const
Definition: SBuf.h:289
uint64_t moves
number of move constructions/assignments
Definition: Stats.h:36
int compare(const char *s, const SBufCaseSensitive isCaseSensitive) const
Definition: SBuf.h:281
#define xmalloc
void cow(size_type minsize=npos)
Definition: SBuf.cc:884
bool startsWith(const SBuf &S, const SBufCaseSensitive isCaseSensitive=caseSensitive) const
Definition: SBuf.cc:452
const_iterator begin() const
Definition: SBuf.h:572
bool operator>(const SBuf &S) const
Definition: SBuf.h:311
SBuf ToLower(SBuf buf)
Returns an upper-cased copy of its parameter.
Definition: SBuf.h:718
MemBlob::size_type size_type
Definition: SBuf.h:52
bool operator==(const SBuf &S) const
Definition: SBuf.cc:465
SBuf & trim(const SBuf &toRemove, bool atBeginning=true, bool atEnd=true)
Definition: SBuf.cc:561
int caseCmp(const SBuf &S) const
Definition: SBuf.h:275
int cmp(const SBuf &S, const size_type n) const
shorthand version for compare()
Definition: SBuf.h:264
static const size_type npos
Definition: SBuf.h:92
size_type find(char c, size_type startPos=0) const
Definition: SBuf.cc:594
static SBufStats stats
class-wide statistics
Definition: SBuf.h:621
Locker(SBuf *parent, const char *otherBuffer)
Definition: SBuf.h:607
#define INT_MAX
Definition: types.h:76
SBufIterator(const SBuf &, size_type)
Definition: SBuf.h:765
size_type len_
number of our content bytes in shared store_
Definition: SBuf.h:620
size_type rfind(char c, size_type endPos=npos) const
Definition: SBuf.cc:702
const_reverse_iterator rend() const
Definition: SBuf.h:584
size_type findFirstNotOf(const CharacterSet &set, size_type startPos=0) const
Definition: SBuf.cc:756
char at(size_type pos) const
Definition: SBuf.h:238
void reserveCapacity(size_type minCapacity)
Definition: SBuf.cc:105
SBuf & vappendf(const char *fmt, va_list vargs)
Definition: SBuf.cc:249
#define DBG_DATA
Definition: Debug.h:48
const char * rawContent() const
Definition: SBuf.cc:519
size_type spaceSize() const
the number unused bytes at the end of the allocated blob
Definition: MemBlob.h:65
size_type findLastOf(const CharacterSet &set, size_type endPos=npos) const
Definition: SBuf.cc:779
MemBlob::size_type size_type
Definition: SBuf.h:89
size_type reserve(const SBufReservationRequirements &requirements)
Definition: SBuf.cc:112
SBuf substr(size_type pos, size_type n=npos) const
Definition: SBuf.cc:586
C * getRaw() const
Definition: RefCount.h:74
size_type copy(char *dest, size_type n) const
Definition: SBuf.cc:510
const InstanceId< SBuf > id
Definition: SBuf.h:593
size_type estimateCapacity(size_type desired) const
Definition: SBuf.h:647
#define NULL
Definition: types.h:166
MemBlob::Pointer locket
Definition: SBuf.h:614
SBuf()
create an empty (zero-size) SBuf
Definition: SBuf.cc:28
SBuf & append(const char *S)
Definition: SBuf.h:197
const char * iter
Definition: SBuf.h:62
bool operator<=(const SBuf &S) const
Definition: SBuf.h:312
size_type spaceSize() const
Definition: SBuf.h:382
uint64_t getChar
number of calls to at() and operator[]
Definition: Stats.h:39
SBuf::size_type size_type
Definition: SBuf.h:688

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors