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 <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
37 typedef enum {
41 
42 class CharacterSet;
43 
49 class SBufIterator : public std::iterator<std::input_iterator_tag, char>
50 {
51 public:
52  friend class SBuf;
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 
60 protected:
61  SBufIterator(const SBuf &, size_type);
62 
63  const char *iter = nullptr;
64 };
65 
72 {
73  friend class SBuf;
74 public:
75  SBufReverseIterator& operator++() { --iter; return *this;}
76  const char &operator*() const { return *(iter-1); }
77 protected:
79 };
80 
87 class SBuf
88 {
89 public:
93  static const size_type npos = 0xffffffff; // max(uint32_t)
94 
96  static const size_type maxSize = 0xfffffff;
97 
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 
117  explicit SBuf(const char *S, size_type n);
118  explicit SBuf(const char *S);
119 
121  explicit SBuf(const std::string &s);
122 
123  ~SBuf();
124 
129  SBuf& assign(const SBuf &S);
130 
135  SBuf& operator =(const SBuf & S) {return assign(S);}
137  ++stats.moves;
138  if (this != &S) {
139  store_ = std::move(S.store_);
140  off_ = S.off_;
141  len_ = S.len_;
142  S.store_ = NULL; //RefCount supports NULL, and S is about to be destructed
143  S.off_ = 0;
144  S.len_ = 0;
145  }
146  return *this;
147  }
148 
159  SBuf& assign(const char *S, size_type n);
160  SBuf& assign(const char *S) {return assign(S,npos);}
161 
168  SBuf& operator =(const char *S) {return assign(S);}
169 
174  void clear();
175 
180  SBuf& append(const SBuf & S);
181 
183  SBuf& append(const char c);
184 
197  SBuf& append(const char * S, size_type Ssize);
198  SBuf& append(const char * S) { return append(S,npos); }
199 
204  SBuf& Printf(const char *fmt, ...);
205 
210  SBuf& appendf(const char *fmt, ...);
211 
216  SBuf& vappendf(const char *fmt, va_list vargs);
217 
219  std::ostream& print(std::ostream &os) const;
220 
226  std::ostream& dump(std::ostream &os) const;
227 
232  char operator [](size_type pos) const {++stats.getChar; return store_->mem[off_+pos];}
233 
239  char at(size_type pos) const {checkAccessBounds(pos); return operator[](pos);}
240 
249  void setAt(size_type pos, char toset);
250 
259  int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive, const size_type n) const;
260  int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive) const {
261  return compare(S, isCaseSensitive, npos);
262  }
263 
265  inline int cmp(const SBuf &S, const size_type n) const {
266  return compare(S,caseSensitive,n);
267  }
268  inline int cmp(const SBuf &S) const {
269  return compare(S,caseSensitive,npos);
270  }
271 
273  inline int caseCmp(const SBuf &S, const size_type n) const {
274  return compare(S,caseInsensitive,n);
275  }
276  inline int caseCmp(const SBuf &S) const {
277  return compare(S,caseInsensitive,npos);
278  }
279 
281  int compare(const char *s, const SBufCaseSensitive isCaseSensitive, const size_type n) const;
282  int compare(const char *s, const SBufCaseSensitive isCaseSensitive) const {
283  return compare(s,isCaseSensitive,npos);
284  }
285 
287  inline int cmp(const char *S, const size_type n) const {
288  return compare(S,caseSensitive,n);
289  }
290  inline int cmp(const char *S) const {
291  return compare(S,caseSensitive,npos);
292  }
293 
295  inline int caseCmp(const char *S, const size_type n) const {
296  return compare(S,caseInsensitive,n);
297  }
298  inline int caseCmp(const char *S) const {
299  return compare(S,caseInsensitive,npos);
300  }
301 
307  bool startsWith(const SBuf &S, const SBufCaseSensitive isCaseSensitive = caseSensitive) const;
308 
309  bool operator ==(const SBuf & S) const;
310  bool operator !=(const SBuf & S) const;
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  bool operator >=(const SBuf &S) const {return (cmp(S) >= 0);}
315 
325  SBuf consume(size_type n = npos);
326 
328  static const SBufStats& GetStats();
329 
336  size_type copy(char *dest, size_type n) const;
337 
363  const char* rawContent() const;
364 
369  char *rawAppendStart(size_type anticipatedSize);
370 
376  void rawAppendFinish(const char *start, size_type actualSize);
377 
383  size_type spaceSize() const { return store_->spaceSize(); }
384 
402  const char* c_str();
403 
405  size_type length() const {return len_;}
406 
412  int plength() const {
413  Must(length() <= INT_MAX);
414  return static_cast<int>(length());
415  }
416 
421  bool isEmpty() const {return (len_==0);}
422 
430  void reserveSpace(size_type minSpace) {
431  Must(minSpace <= maxSize);
432  Must(length() <= maxSize - minSpace);
433  reserveCapacity(length()+minSpace);
434  }
435 
444  void reserveCapacity(size_type minCapacity);
445 
450  size_type reserve(const SBufReservationRequirements &requirements);
451 
466  SBuf& chop(size_type pos, size_type n = npos);
467 
475  SBuf& trim(const SBuf &toRemove, bool atBeginning = true, bool atEnd = true);
476 
483  SBuf substr(size_type pos, size_type n = npos) const;
484 
493  size_type find(char c, size_type startPos = 0) const;
494 
503  size_type find(const SBuf & str, size_type startPos = 0) const;
504 
512  size_type rfind(char c, size_type endPos = npos) const;
513 
522  size_type rfind(const SBuf &str, size_type endPos = npos) const;
523 
534  size_type findFirstOf(const CharacterSet &set, size_type startPos = 0) const;
535 
544  size_type findLastOf(const CharacterSet &set, size_type endPos = npos) const;
545 
554  size_type findFirstNotOf(const CharacterSet &set, size_type startPos = 0) const;
555 
562  size_type findLastNotOf(const CharacterSet &set, size_type endPos = npos) const;
563 
565  void toLower();
566 
568  void toUpper();
569 
571  std::string toStdString() const { return std::string(buf(),length()); }
572 
574  return const_iterator(*this, 0);
575  }
576 
577  const_iterator end() const {
578  return const_iterator(*this, length());
579  }
580 
582  return const_reverse_iterator(*this, length());
583  }
584 
586  return const_reverse_iterator(*this, 0);
587  }
588 
589  // TODO: possibly implement erase() similar to std::string's erase
590  // TODO: possibly implement a replace() call
591 
595 
596 private:
597 
605  class Locker
606  {
607  public:
608  Locker(SBuf *parent, const char *otherBuffer) {
609  // lock if otherBuffer intersects the parents buffer area
610  const MemBlob *blob = parent->store_.getRaw();
611  if (blob->mem <= otherBuffer && otherBuffer < (blob->mem + blob->capacity))
612  locket = blob;
613  }
614  private:
616  };
617  friend class Locker;
618 
622  static SBufStats stats;
623 
630 
635  char * buf() const {return (store_->mem+off_);}
636 
642  char * bufEnd() const {return (store_->mem+off_+len_);}
643 
648  size_type estimateCapacity(size_type desired) const {return (2*desired);}
649 
650  void reAlloc(size_type newsize);
651 
652  void cow(size_type minsize = npos);
653 
654  void checkAccessBounds(const size_type pos) const { Must(pos < length()); }
655 
673  char *rawSpace(size_type minSize);
674 
682  SBuf& lowAppend(const char * memArea, size_type areaSize);
683 };
684 
687 {
688 public:
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  */
699  bool allowShared = true;
700 };
701 
703 inline std::ostream &
704 operator <<(std::ostream& os, const SBuf& S)
705 {
706  return S.print(os);
707 }
708 
710 inline SBuf
712 {
713  buf.toUpper();
714  return buf;
715 }
716 
718 inline SBuf
720 {
721  buf.toLower();
722  return buf;
723 }
724 
741 inline void
742 SBufToCstring(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 
757 inline char *
759 {
760  char *d = static_cast<char*>(xmalloc(s.length()+1));
761  SBufToCstring(d, s);
762  return d;
763 }
764 
765 inline
767  : iter(s.rawContent()+pos)
768 {}
769 
770 inline bool
772 {
773  // note: maybe the sbuf comparison is unnecessary?
774  return iter == s.iter;
775 }
776 
777 inline bool
779 {
780  // note: maybe the sbuf comparison is unnecessary?
781  return iter != s.iter;
782 }
783 
784 #endif /* SQUID_SBUF_H */
785 
int caseCmp(const SBuf &S, const size_type n) const
shorthand version for case-insensitive compare()
Definition: SBuf.h:273
void reserveSpace(size_type minSpace)
Definition: SBuf.h:430
uint32_t size_type
Definition: MemBlob.h:51
std::ostream & operator<<(std::ostream &os, const SBuf &S)
ostream output operator
Definition: SBuf.h:704
~SBuf()
Definition: SBuf.cc:77
const_iterator end() const
Definition: SBuf.h:577
bool operator==(const SBufIterator &s) const
Definition: SBuf.h:771
bool operator>=(const SBuf &S) const
Definition: SBuf.h:314
std::ostream & dump(std::ostream &os) const
Definition: SBuf.cc:326
SBuf & operator=(const SBuf &S)
Definition: SBuf.h:135
SBuf & appendf(const char *fmt,...)
Definition: SBuf.cc:248
SBufReverseIterator & operator++()
Definition: SBuf.h:75
int caseCmp(const char *S, const size_type n) const
Shorthand version for case-insensitive C-string compare().
Definition: SBuf.h:295
SBuf & assign(const SBuf &S)
Definition: SBuf.cc:92
size_type idealSpace
if allocating anyway, provide this much space
Definition: SBuf.h:696
Definition: SBuf.h:87
SBuf(SBuf &&S)
Definition: SBuf.h:101
bool operator!=(const SBufIterator &s) const
Definition: SBuf.h:778
SBuf & append(const SBuf &S)
Definition: SBuf.cc:204
size_type capacity
size of the raw allocated memory block
Definition: MemBlob.h:103
SBufIterator const_iterator
Definition: SBuf.h:91
static const SBufStats & GetStats()
gets global statistic informations
Definition: SBuf.cc:517
SBuf ToUpper(SBuf buf)
Returns a lower-cased copy of its parameter.
Definition: SBuf.h:711
SBuf & chop(size_type pos, size_type n=npos)
Definition: SBuf.cc:553
std::ostream & print(std::ostream &os) const
print the SBuf contents to the supplied ostream
Definition: SBuf.cc:318
size_type findLastNotOf(const CharacterSet &set, size_type endPos=npos) const
Definition: SBuf.cc:813
void clear()
Definition: SBuf.cc:187
#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:311
const_reverse_iterator rbegin() const
Definition: SBuf.h:581
void toUpper()
converts all characters to upper case;
Definition: SBuf.cc:847
bool isEmpty() const
Definition: SBuf.h:421
MemBlob::Pointer store_
memory block, possibly shared with other SBufs
Definition: SBuf.h:619
SBufReverseIterator const_reverse_iterator
Definition: SBuf.h:92
int plength() const
Definition: SBuf.h:412
void SBufToCstring(char *d, const SBuf &s)
Definition: SBuf.h:742
static const size_type maxSize
Maximum size of a SBuf. By design it MUST be < MAX(size_type)/2. Currently 256Mb. ...
Definition: SBuf.h:96
const char & operator*() const
Definition: SBuf.h:57
void checkAccessBounds(const size_type pos) const
Definition: SBuf.h:654
char operator[](size_type pos) const
Definition: SBuf.h:232
char * buf() const
Definition: SBuf.h:635
void setAt(size_type pos, char toset)
Definition: SBuf.cc:351
static MemBlob::Pointer GetStorePrototype()
Definition: SBuf.cc:85
std::string toStdString() const
std::string export function
Definition: SBuf.h:571
SBuf & lowAppend(const char *memArea, size_type areaSize)
Definition: SBuf.cc:882
void rawAppendFinish(const char *start, size_type actualSize)
Definition: SBuf.cc:153
void reAlloc(size_type newsize)
Definition: SBuf.cc:868
void toLower()
converts all characters to lower case;
Definition: SBuf.cc:834
SBufCaseSensitive
Definition: SBuf.h:37
Named SBuf::reserve() parameters. Defaults ask for and restrict nothing.
Definition: SBuf.h:686
size_type length() const
Returns the number of bytes stored in SBuf.
Definition: SBuf.h:405
SBufReverseIterator(const SBuf &s, size_type sz)
Definition: SBuf.h:78
char * rawAppendStart(size_type anticipatedSize)
Definition: SBuf.cc:145
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:121
size_type maxCapacity
do not allocate more than this
Definition: SBuf.h:698
bool operator!=(const SBuf &S) const
Definition: SBuf.cc:498
SBuf & Printf(const char *fmt,...)
Definition: SBuf.cc:233
int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive) const
Definition: SBuf.h:260
size_type off_
our content start offset from the beginning of shared store_
Definition: SBuf.h:620
char * bufEnd() const
Definition: SBuf.h:642
SBuf & assign(const char *S)
Definition: SBuf.h:160
const char * c_str()
Definition: SBuf.cc:539
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:699
int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive, const size_type n) const
Definition: SBuf.cc:375
char * mem
raw allocated memory block
Definition: MemBlob.h:102
int caseCmp(const char *S) const
Definition: SBuf.h:298
SBuf consume(size_type n=npos)
Definition: SBuf.cc:504
char * rawSpace(size_type minSize)
Definition: SBuf.cc:166
void const char * buf
Definition: stub_helper.cc:16
const char & operator*() const
Definition: SBuf.h:76
int cmp(const char *S, const size_type n) const
Shorthand version for C-string compare().
Definition: SBuf.h:287
size_type minSpace
allocate [at least this much] if spaceSize() is smaller
Definition: SBuf.h:697
int cmp(const SBuf &S) const
Definition: SBuf.h:268
SBufIterator & operator++()
Definition: SBuf.h:58
size_type findFirstOf(const CharacterSet &set, size_type startPos=0) const
Definition: SBuf.cc:746
int cmp(const char *S) const
Definition: SBuf.h:290
uint64_t moves
number of move constructions/assignments
Definition: Stats.h:36
int compare(const char *s, const SBufCaseSensitive isCaseSensitive) const
Definition: SBuf.h:282
#define xmalloc
void cow(size_type minsize=npos)
Definition: SBuf.cc:897
bool startsWith(const SBuf &S, const SBufCaseSensitive isCaseSensitive=caseSensitive) const
Definition: SBuf.cc:465
const_iterator begin() const
Definition: SBuf.h:573
bool operator>(const SBuf &S) const
Definition: SBuf.h:312
SBuf ToLower(SBuf buf)
Returns an upper-cased copy of its parameter.
Definition: SBuf.h:719
MemBlob::size_type size_type
Definition: SBuf.h:53
bool operator==(const SBuf &S) const
Definition: SBuf.cc:478
SBuf & trim(const SBuf &toRemove, bool atBeginning=true, bool atEnd=true)
Definition: SBuf.cc:574
int caseCmp(const SBuf &S) const
Definition: SBuf.h:276
int cmp(const SBuf &S, const size_type n) const
shorthand version for compare()
Definition: SBuf.h:265
static const size_type npos
Definition: SBuf.h:93
size_type find(char c, size_type startPos=0) const
Definition: SBuf.cc:607
static SBufStats stats
class-wide statistics
Definition: SBuf.h:622
Locker(SBuf *parent, const char *otherBuffer)
Definition: SBuf.h:608
#define INT_MAX
Definition: types.h:76
SBufIterator(const SBuf &, size_type)
Definition: SBuf.h:766
size_type len_
number of our content bytes in shared store_
Definition: SBuf.h:621
size_type rfind(char c, size_type endPos=npos) const
Definition: SBuf.cc:715
const_reverse_iterator rend() const
Definition: SBuf.h:585
size_type findFirstNotOf(const CharacterSet &set, size_type startPos=0) const
Definition: SBuf.cc:769
char at(size_type pos) const
Definition: SBuf.h:239
void reserveCapacity(size_type minCapacity)
Definition: SBuf.cc:114
SBuf & vappendf(const char *fmt, va_list vargs)
Definition: SBuf.cc:258
#define DBG_DATA
Definition: Debug.h:48
const char * rawContent() const
Definition: SBuf.cc:532
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:792
MemBlob::size_type size_type
Definition: SBuf.h:90
size_type reserve(const SBufReservationRequirements &requirements)
Definition: SBuf.cc:121
SBuf substr(size_type pos, size_type n=npos) const
Definition: SBuf.cc:599
C * getRaw() const
Definition: RefCount.h:74
size_type copy(char *dest, size_type n) const
Definition: SBuf.cc:523
const InstanceId< SBuf > id
Definition: SBuf.h:594
size_type estimateCapacity(size_type desired) const
Definition: SBuf.h:648
#define NULL
Definition: types.h:166
MemBlob::Pointer locket
Definition: SBuf.h:615
SBuf()
create an empty (zero-size) SBuf
Definition: SBuf.cc:37
SBuf & append(const char *S)
Definition: SBuf.h:198
const char * iter
Definition: SBuf.h:63
bool operator<=(const SBuf &S) const
Definition: SBuf.h:313
size_type spaceSize() const
Definition: SBuf.h:383
uint64_t getChar
number of calls to at() and operator[]
Definition: Stats.h:39
SBuf::size_type size_type
Definition: SBuf.h:689

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors