]> git.ipfire.org Git - thirdparty/squid.git/blame - src/SquidString.h
Maintenance: update MemBlob (#2106)
[thirdparty/squid.git] / src / SquidString.h
CommitLineData
0f15e632 1/*
1f7b830e 2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
0f15e632 3 *
bbc27441
AJ
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.
0f15e632 7 */
8
bbc27441
AJ
9/* DEBUG: section 67 String */
10
ff9d9458
FC
11#ifndef SQUID_SRC_SQUIDSTRING_H
12#define SQUID_SRC_SQUIDSTRING_H
0f15e632 13
f63c4b05 14#include "base/TextException.h"
675b8408 15#include "debug/Stream.h"
e93eda7e 16#include "sbuf/forward.h"
f63c4b05 17
e1f7507e
AJ
18#include <ostream>
19
bb790702
FC
20/* squid string placeholder (for printf) */
21#ifndef SQUIDSTRINGPH
22#define SQUIDSTRINGPH "%.*s"
b716b3d4 23#define SQUIDSTRINGPRINT(s) (s).psize(),(s).rawBuf()
bb790702
FC
24#endif /* SQUIDSTRINGPH */
25
30abd221 26class String
27{
0353e724 28
30abd221 29public:
8ee00d73 30 String() = default;
9e9ef416
RP
31 String(char const *);
32 String(String const &);
20a04c12
AJ
33 String(String && S) : size_(S.size_), len_(S.len_), buf_(S.buf_) {
34 S.buf_ = nullptr; // S is about to be destructed
35 S.size_ = S.len_ = 0;
36 }
30abd221 37 ~String();
38
b4197865 39 typedef size_t size_type; //storage size intentionally unspecified
556bfec0 40 const static size_type npos = static_cast<size_type>(-1);
a7a42b14 41
30abd221 42 String &operator =(char const *);
43 String &operator =(String const &);
20a04c12
AJ
44 String &operator =(String && S) {
45 if (this != &S) {
9c62c979 46 clean();
20a04c12
AJ
47 size_ = S.size_;
48 len_ = S.len_;
49 buf_ = S.buf_;
50 S.size_ = 0;
51 S.len_ = 0;
52 S.buf_ = nullptr; // S is about to be destructed
53 }
54 return *this;
55 }
56
30abd221 57 bool operator ==(String const &) const;
58 bool operator !=(String const &) const;
59
3db44fdf 60 /**
61 * Retrieve a single character in the string.
f63c4b05 62 \param aPos Position of character to retrieve.
3db44fdf 63 */
f63c4b05
AJ
64 char operator [](unsigned int aPos) const {
65 assert(aPos < size_);
66 return buf_[aPos];
67 }
68
90be6ff5
EB
69 /// The absolute size limit on data held in a String.
70 /// Since Strings can be nil-terminated implicitly it is best to ensure
71 /// the useful content length is strictly less than this limit.
98d0df03 72 static size_type SizeMaxXXX() { return SizeMax_; }
90be6ff5 73
f63c4b05 74 size_type size() const { return len_; }
3db44fdf 75
9b558d8a 76 /// variant of size() suited to be used for printf-alikes.
f63c4b05
AJ
77 /// throws when size() >= INT_MAX
78 int psize() const {
79 Must(size() < INT_MAX);
80 return size();
81 }
99524de7 82
99524de7
FC
83 /**
84 * Returns a raw pointer to the underlying backing store. The caller has been
85 * verified not to make any assumptions about null-termination
86 */
f63c4b05
AJ
87 char const * rawBuf() const { return buf_; }
88
99524de7
FC
89 /**
90 * Returns a raw pointer to the underlying backing store.
91 * The caller requires it to be null-terminated.
92 */
f63c4b05
AJ
93 char const * termedBuf() const { return buf_; }
94
2fe0439c 95 void assign(const char *str, int len);
30abd221 96 void clean();
97 void reset(char const *str);
98 void append(char const *buf, int len);
99 void append(char const *buf);
100 void append(char const);
9e9ef416 101 void append(String const &);
e93eda7e 102 void append(const SBuf &); ///< adds the entire given buffer
30abd221 103 void absorb(String &old);
826a1fed
FC
104 const char * pos(char const *aString) const;
105 const char * pos(char const ch) const;
b4f2886c 106 ///offset from string start of the first occurrence of ch
2c1fd837 107 /// returns String::npos if ch is not found
826a1fed
FC
108 size_type find(char const ch) const;
109 size_type find(char const *aString) const;
110 const char * rpos(char const ch) const;
111 size_type rfind(char const ch) const;
f63c4b05
AJ
112 int cmp(char const *) const;
113 int cmp(char const *, size_type count) const;
114 int cmp(String const &) const;
115 int caseCmp(char const *) const;
116 int caseCmp(char const *, size_type count) const;
117 int caseCmp(String const &str) const {
118 return caseCmp(str.rawBuf(),str.size());
119 }
30abd221 120
70df76e3
AR
121 /// Whether creating a totalLen-character string is safe (i.e., unlikely to assert).
122 /// Optional extras can be used for overflow-safe length addition.
123 /// Implementation has to add 1 because many String allocation methods do.
124 static bool CanGrowTo(size_type totalLen, const size_type extras = 0) { return SafeAdd(totalLen, extras) && SafeAdd(totalLen, 1); }
125 /// whether appending growthLen characters is safe (i.e., unlikely to assert)
126 bool canGrowBy(const size_type growthLen) const { return CanGrowTo(size(), growthLen); }
127
a7a42b14 128 String substr(size_type from, size_type to) const;
9b558d8a 129
f63c4b05 130 void cut(size_type newLength);
30abd221 131
30abd221 132private:
e7e1bf60 133 void allocAndFill(const char *str, int len);
a7a42b14
FC
134 void allocBuffer(size_type sz);
135 void setBuffer(char *buf, size_type sz);
e7e1bf60 136
aee3523a 137 bool defined() const {return buf_!=nullptr;}
b38b26cb
AJ
138 bool undefined() const {return !defined();}
139
30abd221 140 /* never reference these directly! */
f63c4b05 141 size_type size_ = 0; /* buffer size; limited by SizeMax_ */
30abd221 142
f63c4b05 143 size_type len_ = 0; /* current length */
30abd221 144
801593a9
AR
145 /// An earlier 64KB limit was meant to protect some fixed-size buffers, but
146 /// (a) we do not know where those buffers are (or whether they still exist)
147 /// (b) too many String users unknowingly exceeded that limit and asserted.
148 /// We are now using a larger limit to reduce the number of (b) cases,
149 /// especially cases where "compact" lists of items grow 50% in size when we
150 /// convert them to canonical form. The new limit is selected to withstand
151 /// concatenation and ~50% expansion of two HTTP headers limited by default
152 /// request_header_max_size and reply_header_max_size settings.
153 static const size_type SizeMax_ = 3*64*1024 - 1;
154
70df76e3
AR
155 /// returns true after increasing the first argument by extra if the sum does not exceed SizeMax_
156 static bool SafeAdd(size_type &base, size_type extra) { if (extra <= SizeMax_ && base <= SizeMax_ - extra) { base += extra; return true; } return false; }
157
f63c4b05 158 char *buf_ = nullptr;
9b558d8a 159
f63c4b05
AJ
160 void set(char const *loc, char const ch) {
161 if (loc < buf_ || loc > (buf_ + size_))
162 return;
163 buf_[loc-buf_] = ch;
164 }
9b558d8a 165
f63c4b05
AJ
166 void cutPointer(char const *loc) {
167 if (loc < buf_ || loc > (buf_ + size_))
168 return;
169 len_ = loc-buf_;
170 buf_[len_] = '\0';
171 }
30abd221 172};
173
f63c4b05
AJ
174inline std::ostream & operator<<(std::ostream &os, String const &aString)
175{
176 os.write(aString.rawBuf(),aString.size());
177 return os;
178}
634592a6 179
f63c4b05
AJ
180inline bool operator<(const String &a, const String &b)
181{
182 return a.cmp(b) < 0;
183}
0f15e632 184
8a648e8d
FC
185const char *checkNullString(const char *p);
186int stringHasWhitespace(const char *);
187int stringHasCntl(const char *);
188char *strwordtok(char *buf, char **t);
0875c529 189
ff9d9458 190#endif /* SQUID_SRC_SQUIDSTRING_H */
f53969cc 191