Click
Loading...
Searching...
No Matches
string.hh
Go to the documentation of this file.
1// -*- related-file-name: "../../lib/string.cc" -*-
2#ifndef CLICK_STRING_HH
3#define CLICK_STRING_HH
4#include <click/algorithm.hh>
5#include <click/atomic.hh>
6#include <click/vector.hh>
7#if HAVE_STRING_PROFILING
8# include <click/integers.hh>
9#endif
10#if CLICK_LINUXMODULE || CLICK_BSDMODULE
11# include <click/glue.hh>
12#else
13# include <string.h>
14#endif
15#if HAVE_AVX2
16#include <immintrin.h>
17#endif
18#define CLICK_CONSTANT_CSTR(cstr) ((cstr) && __builtin_constant_p(strlen((cstr))))
19CLICK_DECLS
20class StringAccum;
21
22class String { public:
23
24 typedef const char *const_iterator;
25 typedef const_iterator iterator;
26
27 typedef int (String::*unspecified_bool_type)() const;
28
29#if HAVE_INT64_TYPES && (!HAVE_LONG_LONG || SIZEOF_LONG_LONG <= 8)
30 typedef int64_t intmax_t;
31 typedef uint64_t uintmax_t;
32#elif HAVE_LONG_LONG
33 typedef long long intmax_t;
34 typedef unsigned long long uintmax_t;
35#else
36 typedef long intmax_t;
37 typedef unsigned long uintmax_t;
38#endif
39 typedef intmax_t int_large_t;
40 typedef uintmax_t uint_large_t;
41
42 inline String();
43 inline String(const String& x);
44#if HAVE_CXX_RVALUE_REFERENCES
45 inline String(String&& x);
46#endif
47 inline String(const char* cstr);
48 inline String(const char* s, int len);
49 inline String(const unsigned char* s, int len);
50 inline String(const char* first, const char* last);
51 inline String(const unsigned char* first, const unsigned char* last);
52 explicit inline String(bool x);
53 explicit inline String(char c);
54 explicit inline String(unsigned char c);
55 explicit String(int x);
56 explicit String(unsigned x);
57 explicit String(long x);
58 explicit String(unsigned long x);
59#if HAVE_LONG_LONG
60 explicit String(long long x);
61 explicit String(unsigned long long x);
62#endif
63#if HAVE_INT64_TYPES && !HAVE_INT64_IS_LONG && !HAVE_INT64_IS_LONG_LONG
64 explicit String(int64_t x);
65 explicit String(uint64_t x);
66#endif
67#if HAVE_FLOAT_TYPES
68 explicit String(double x);
69#endif
70 inline ~String();
71
72 static inline const String& make_empty();
73 static inline String make_uninitialized(int len);
74 static inline String make_garbage(int len) CLICK_DEPRECATED;
75 static inline String make_stable(const char* cstr);
76 static inline String make_stable(const char* s, int len);
77 static inline String make_stable(const char* first, const char* last);
78 static String make_numeric(intmax_t x, int base = 10, bool uppercase = true);
79 static String make_numeric(uintmax_t x, int base = 10, bool uppercase = true);
80
81 inline const char* data() const;
82 inline int length() const;
83
84 inline const char *c_str() const;
85
86 inline operator unspecified_bool_type() const;
87 inline bool empty() const;
88 inline bool operator!() const;
89
90 inline const_iterator begin() const;
91 inline const_iterator end() const;
92
93 inline char operator[](int i) const;
94 inline char at(int i) const;
95 inline char front() const;
96 inline char back() const;
97
98 static uint32_t hashcode(const char *begin, const char *end);
99 static inline uint32_t hashcode(const unsigned char *begin,
100 const unsigned char *end);
101 inline uint32_t hashcode() const;
102
103 inline String substring(const char *begin, const char *end) const;
104 String substring(int pos, int len) const;
105 inline String substring(int pos) const;
106 String trim() const;
107 String trim_space() const;
108 String trim_space_left() const;
109 String remove(char c) const;
110 String replace(char from, char to) const;
111 String replace(String from, String to) const;
112
113 inline bool equals(const String &x) const;
114 inline bool equals(const char *s, int len) const;
115 static inline int compare(const String &a, const String &b);
116 inline int compare(const String &x) const;
117 int compare(const char *s, int len) const;
118 inline bool starts_with(const String &x) const;
119 bool starts_with(const char *s, int len) const;
120 bool glob_match(const String& pattern) const;
121
122 // bool operator==(const String &, const String &);
123 // bool operator==(const String &, const char *);
124 // bool operator==(const char *, const String &);
125 // bool operator!=(const String &, const String &);
126 // bool operator!=(const String &, const char *);
127 // bool operator!=(const char *, const String &);
128 // bool operator<(const String &, const String &);
129 // bool operator<=(const String &, const String &);
130 // bool operator>(const String &, const String &);
131 // bool operator>=(const String &, const String &);
132 Vector<String> split(char c) const;
133
134 int find_left(char c, int start = 0) const;
135 int find_left(const String &x, int start = 0) const;
136 int find_right(char c, int start = 0x7FFFFFFF) const;
137
138 const char* search(String pattern);
139
140 String lower() const;
141 String upper() const;
142 String printable() const;
143 String quoted_hex() const;
144 String encode_json() const;
145
146 inline String &operator=(const String &x);
147#if HAVE_CXX_RVALUE_REFERENCES
148 inline String &operator=(String &&x);
149#endif
150 inline String &operator=(const char *cstr);
151
152 inline void swap(String &x);
153
154 inline void append(const String &x);
155 inline void append(const char *cstr);
156 inline void append(const char *s, int len);
157 inline void append(const char *first, const char *last);
158 inline void append(char c);
159 void append_fill(int c, int len);
160 char *append_uninitialized(int len);
161 inline char *append_garbage(int len) CLICK_DEPRECATED;
162
163 inline String &operator+=(const String &x);
164 inline String &operator+=(const char *cstr);
165 inline String &operator+=(char c);
166
167 // String operator+(String, const String &);
168 // String operator+(String, const char *);
169 // String operator+(const char *, const String &);
170
171 inline bool is_shared() const;
172 inline bool is_stable() const;
173
174 inline String unique() const CLICK_DEPRECATED;
175 inline String unshared() const;
176 inline String compact() const;
177
178 char *mutable_data();
179 char *mutable_c_str();
180
181 static inline const String &make_out_of_memory();
182 inline bool out_of_memory() const;
183 static inline const char *out_of_memory_data();
184 static inline int out_of_memory_length();
185 static inline const char *empty_data();
186
187#if HAVE_STRING_PROFILING
188 static void profile_report(StringAccum &sa, int examples = 0);
189#endif
190
191 static inline const char *skip_utf8_char(const char *first, const char *last);
192 static const unsigned char *skip_utf8_char(const unsigned char *first,
193 const unsigned char *last);
194
195 static const char bool_data[11];
196
197 private:
198
200 struct memo_t {
201 volatile uint32_t refcount;
202 uint32_t capacity;
203 volatile uint32_t dirty;
204#if HAVE_STRING_PROFILING > 1
205 memo_t **pprev;
206 memo_t *next;
207#endif
208 char real_data[8]; // but it might be more or less
209 };
210
211 enum {
212 MEMO_SPACE = sizeof(memo_t) - 8
213 };
214
215 struct rep_t {
216 const char *data;
217 int length;
218 memo_t *memo;
219 };
222 mutable rep_t _r; // mutable for c_str()
223
224#if HAVE_STRING_PROFILING
225 static uint64_t live_memo_count;
226 static uint64_t memo_sizes[55];
227 static uint64_t live_memo_sizes[55];
228 static uint64_t live_memo_bytes[55];
229# if HAVE_STRING_PROFILING > 1
230 static memo_t *live_memos[55];
231# endif
232
233 static inline int profile_memo_size_bucket(uint32_t dirty, uint32_t capacity) {
234 if (capacity <= 16)
235 return dirty;
236 else if (capacity <= 32)
237 return 17 + (capacity - 17) / 2;
238 else if (capacity <= 64)
239 return 25 + (capacity - 33) / 8;
240 else
241 return 29 + 26 - ffs_msb(capacity - 1);
242 }
243
244 static void profile_update_memo_dirty(memo_t *memo, uint32_t old_dirty, uint32_t new_dirty, uint32_t capacity) {
245 if (capacity <= 16 && new_dirty != old_dirty) {
246 ++memo_sizes[new_dirty];
247 ++live_memo_sizes[new_dirty];
248 live_memo_bytes[new_dirty] += capacity;
249 --live_memo_sizes[old_dirty];
250 live_memo_bytes[old_dirty] -= capacity;
251# if HAVE_STRING_PROFILING > 1
252 if ((*memo->pprev = memo->next))
253 memo->next->pprev = memo->pprev;
254 memo->pprev = &live_memos[new_dirty];
255 if ((memo->next = *memo->pprev))
256 memo->next->pprev = &memo->next;
257 *memo->pprev = memo;
258# else
259 (void) memo;
260# endif
261 }
262 }
263
264 static void one_profile_report(StringAccum &sa, int i, int examples);
265#endif
266
267 const char* searchLegacy(const char* pattern, const int pattern_length);
268#if HAVE_AVX2 && !defined(CLICK_TOOL)
269 inline const char* searchAVX2(const char* pattern, const int pattern_length);
270#endif
271
272 inline void assign_memo(const char *data, int length, memo_t *memo) const {
273 _r.data = data;
274 _r.length = length;
275 if ((_r.memo = memo))
276 atomic_uint32_t::inc(memo->refcount);
277 }
278
279 inline String(const char *data, int length, memo_t *memo) {
280 assign_memo(data, length, memo);
281 }
282
283 inline void assign(const String &x) const {
284 assign_memo(x._r.data, x._r.length, x._r.memo);
285 }
286
287 inline void deref() const {
288 if (_r.memo) {
289 assert(_r.memo->refcount);
290 if (atomic_uint32_t::dec_and_test(_r.memo->refcount))
291 delete_memo(_r.memo);
292 _r.memo = 0;
293 }
294 }
295
296 void assign(const char *s, int len, bool need_deref);
297 void assign_out_of_memory();
298 void append(const char *s, int len, memo_t *memo);
299 static String hard_make_stable(const char *s, int len);
300 static inline memo_t *absent_memo() {
301 return reinterpret_cast<memo_t *>(uintptr_t(1));
302 }
303 static memo_t *create_memo(char *space, int dirty, int capacity);
304 static void delete_memo(memo_t *memo);
305 const char *hard_c_str() const;
306 bool hard_equals(const char *s, int len) const;
307
308 static const char null_data;
309 static const char oom_data[15];
310 static const char int_data[20];
311 static const rep_t null_string_rep;
312 static const rep_t oom_string_rep;
313 enum { oom_len = 14 };
314
315 static String make_claim(char *, int, int); // claim memory
316
317 friend struct rep_t;
318 friend class StringAccum;
319
320};
321
322class StringRef {
323 public:
324
325 inline StringRef();
326 inline StringRef(const StringRef &x);
327 inline StringRef(const char *cstr);
328 inline StringRef(const char *s, int len);
329 inline StringRef(const char *b, const char* end);
330 inline StringRef(const String &x);
331
332 inline const char *data() const;
333 inline int length() const;
334
335 inline const char *begin() const;
336 inline const char *end() const;
337
338 inline uint32_t hashcode() const;
339
340 inline bool operator==(const StringRef &o) {
341 return o.len_ == len_ && memcmp(data_, o.data_, len_) == 0;
342 }
343
344 private:
345 const char *data_;
346 int len_;
347};
348
349inline StringRef operator "" _s(const char *str, std::size_t len) {
350 return StringRef(str, len);
351}
352
355 assign_memo(&null_data, 0, 0);
356}
357
359inline String::String(const String &x) {
360 assign(x);
361}
362
363#if HAVE_CXX_RVALUE_REFERENCES
365inline String::String(String &&x)
366 : _r(x._r) {
367 x._r.memo = 0;
368}
369#endif
370
375inline String::String(const char *cstr) {
376 if (CLICK_CONSTANT_CSTR(cstr))
377 assign_memo(cstr, strlen(cstr), 0);
378 else
379 assign(cstr, -1, false);
380}
381
388inline String::String(const char *s, int len) {
389 assign(s, len, false);
390}
391
393inline String::String(const unsigned char *s, int len) {
394 assign(reinterpret_cast<const char *>(s), len, false);
395}
396
404inline String::String(const char *first, const char *last) {
405 assign(first, (first < last ? last - first : 0), false);
406}
407
409inline String::String(const unsigned char *first, const unsigned char *last) {
410 assign(reinterpret_cast<const char *>(first),
411 (first < last ? last - first : 0), false);
412}
413
416inline String::String(bool x) {
417 // bool_data equals "false\0true\0"
418 assign_memo(bool_data + (-x & 6), 5 - x, 0);
419}
420
422inline String::String(char c) {
423 assign(&c, 1, false);
424}
425
427inline String::String(unsigned char c) {
428 assign(reinterpret_cast<char *>(&c), 1, false);
429}
430
433 deref();
434}
435
439inline const String &String::make_empty() {
440 return reinterpret_cast<const String &>(null_string_rep);
441}
442
445 String s;
447 return s;
448}
449
451inline String String::make_garbage(int len) {
452 return make_uninitialized(len);
453}
463inline String String::make_stable(const char *cstr) {
464 if (CLICK_CONSTANT_CSTR(cstr))
465 return String(cstr, strlen(cstr), 0);
466 else
467 return hard_make_stable(cstr, -1);
468}
469
477inline String String::make_stable(const char *s, int len) {
478 if (__builtin_constant_p(len) && len >= 0)
479 return String(s, len, 0);
480 else
481 return hard_make_stable(s, len);
482}
483
496inline String String::make_stable(const char *first, const char *last) {
497 return String(first, (first < last ? last - first : 0), 0);
498}
499
504inline const char *String::data() const {
505 return _r.data;
506}
507
509inline int String::length() const {
510 return _r.length;
511}
512
519inline const char *String::c_str() const {
520 // See also hard_c_str().
521#if CLICK_OPTIMIZE_SIZE || __OPTIMIZE_SIZE__
522 return hard_c_str();
523#else
524 // We may already have a '\0' in the right place. If _memo has no
525 // capacity, then this is one of the special strings (null or
526 // stable). We are guaranteed, in these strings, that _data[_length]
527 // exists. Otherwise must check that _data[_length] exists.
528 const char *end_data = _r.data + _r.length;
529 if ((_r.memo && end_data >= _r.memo->real_data + _r.memo->dirty)
530 || *end_data != '\0') {
531 if (char *x = const_cast<String *>(this)->append_uninitialized(1)) {
532 *x = '\0';
533 --_r.length;
534 }
535 }
536 return _r.data;
537#endif
538}
539
550inline String String::substring(const char *first, const char *last) const {
551 if (first < last && first >= _r.data && last <= _r.data + _r.length)
552 return String(first, last - first, _r.memo);
553 else
554 return String();
555}
556
568inline String String::substring(int pos) const {
569 return substring((pos <= -_r.length ? 0 : pos), _r.length);
570}
571
576inline String::const_iterator String::begin() const {
577 return _r.data;
578}
579
584inline String::const_iterator String::end() const {
585 return _r.data + _r.length;
586}
587
589inline String::operator unspecified_bool_type() const {
590 return (_r.length != 0 ? &String::length : 0);
591}
592
594inline bool String::empty() const {
595 return _r.length == 0;
596}
597
599inline bool String::operator!() const {
600 return empty();
601}
602
606inline char String::operator[](int i) const {
607 return _r.data[i];
608}
609
614inline char String::at(int i) const {
615 assert((unsigned) i < (unsigned) _r.length);
616 return _r.data[i];
617}
618
622inline char String::front() const {
623 return _r.data[0];
624}
625
629inline char String::back() const {
630 return _r.data[_r.length - 1];
631}
632
634inline uint32_t String::hashcode(const unsigned char *first,
635 const unsigned char *last) {
636 return hashcode(reinterpret_cast<const char *>(first),
637 reinterpret_cast<const char *>(last));
638}
639
646inline uint32_t String::hashcode() const {
647 return (length() ? hashcode(begin(), end()) : 0);
648}
649
651inline bool String::equals(const String &x) const {
652 return equals(x.data(), x.length());
653}
654
663inline bool String::equals(const char *s, int len) const {
664#if CLICK_OPTIMIZE_SIZE || __OPTIMIZE_SIZE__
665 return hard_equals(s, len);
666#else
667 if (__builtin_constant_p(len) && len >= 0)
668 return length() == len && memcmp(data(), s, len) == 0;
669 else
670 return hard_equals(s, len);
671#endif
672}
673
681inline int String::compare(const String &a, const String &b) {
682 return a.compare(b);
683}
684
689inline int String::compare(const String &x) const {
690 return compare(x.data(), x.length());
691}
692
696inline bool String::starts_with(const String &x) const {
697 return starts_with(x.data(), x.length());
698}
699
701inline String &String::operator=(const String &x) {
702 if (likely(&x != this)) {
703 deref();
704 assign(x);
705 }
706 return *this;
707}
708
709#if HAVE_CXX_RVALUE_REFERENCES
711inline String &String::operator=(String &&x) {
712 deref();
713 _r = x._r;
714 x._r.memo = 0;
715 return *this;
716}
717#endif
718
720inline String &String::operator=(const char *cstr) {
721 if (CLICK_CONSTANT_CSTR(cstr)) {
722 deref();
723 assign_memo(cstr, strlen(cstr), 0);
724 } else
725 assign(cstr, -1, true);
726 return *this;
727}
728
730inline void String::swap(String &x) {
731 rep_t r = _r;
732 _r = x._r;
733 x._r = r;
734}
735
737inline void String::append(const String &x) {
738 append(x.data(), x.length(), x._r.memo);
739}
740
743inline void String::append(const char *cstr) {
744 if (CLICK_CONSTANT_CSTR(cstr))
745 append(cstr, strlen(cstr), absent_memo());
746 else
747 append(cstr, -1, absent_memo());
748}
749
754inline void String::append(const char *s, int len) {
755 append(s, len, absent_memo());
756}
757
761inline void String::append(const char *first, const char *last) {
762 if (first < last)
763 append(first, last - first);
764}
765
767inline void String::append(char c) {
768 append(&c, 1, absent_memo());
769}
770
772inline char *String::append_garbage(int len) {
773 return append_uninitialized(len);
774}
780 append(x.data(), x.length(), x._r.memo);
781 return *this;
782}
783
786inline String &String::operator+=(const char *cstr) {
787 append(cstr);
788 return *this;
789}
790
793inline String &String::operator+=(char c) {
794 append(&c, 1);
795 return *this;
796}
797
799inline bool String::is_shared() const {
800 return !_r.memo || _r.memo->refcount != 1;
801}
802
804inline bool String::is_stable() const {
805 return !_r.memo;
806}
807
811inline String String::unshared() const {
812 if (!_r.memo || _r.memo->refcount == 1)
813 return *this;
814 else
815 return String(_r.data, _r.data + _r.length);
816}
817
822inline String String::unique() const {
823 return unshared();
824}
825
830inline String String::compact() const {
831 if (!_r.memo || _r.memo->refcount == 1
832 || (uint32_t) _r.length + 256 >= _r.memo->capacity)
833 return *this;
834 else
835 return String(_r.data, _r.data + _r.length);
836}
837
839inline bool String::out_of_memory() const {
840 return unlikely(data() == oom_data);
841}
842
845 return reinterpret_cast<const String &>(oom_string_rep);
846}
847
849inline const char *String::out_of_memory_data() {
850 return oom_data;
851}
852
855 return oom_len;
856}
857
862inline const char *String::empty_data() {
863 return &null_data;
864}
865
870inline const char *String::skip_utf8_char(const char *first, const char *last) {
871 return reinterpret_cast<const char *>(skip_utf8_char(reinterpret_cast<const unsigned char *>(first), reinterpret_cast<const unsigned char *>(last)));
872}
873
874inline StringRef::StringRef()
875 : data_(0), len_(0) {
876}
877
878inline StringRef::StringRef(const StringRef &x)
879 : data_(x.data_), len_(x.len_) {
880}
881
882inline StringRef::StringRef(const char *cstr)
883 : data_(cstr), len_(strlen(cstr)) {
884}
885
886inline StringRef::StringRef(const char *s, int len)
887 : data_(s), len_(len) {
888}
889
890inline StringRef::StringRef(const char *b, const char* end) : data_(b), len_(end - b) {
891}
892
893inline StringRef::StringRef(const String &x)
894 : data_(x.data()), len_(x.length()) {
895}
896
897inline const char *StringRef::data() const {
898 return data_;
899}
900
901inline int StringRef::length() const {
902 return len_;
903}
904
905inline const char *StringRef::begin() const {
906 return data();
907}
908
909inline const char *StringRef::end() const {
910 return data() + length();
911}
912
920inline bool operator==(const String &a, const String &b) {
921 return a.equals(b.data(), b.length());
922}
923
925inline bool operator==(const char *a, const String &b) {
926 if (CLICK_CONSTANT_CSTR(a))
927 return b.equals(a, strlen(a));
928 else
929 return b.equals(a, -1);
930}
931
933inline bool operator==(const String &a, const char *b) {
934 if (CLICK_CONSTANT_CSTR(b))
935 return a.equals(b, strlen(b));
936 else
937 return a.equals(b, -1);
938}
939
945inline bool operator!=(const String &a, const String &b) {
946 return !(a == b);
947}
948
950inline bool operator!=(const char *a, const String &b) {
951 return !(a == b);
952}
953
955inline bool operator!=(const String &a, const char *b) {
956 return !(a == b);
957}
958
964inline bool operator<(const String &a, const String &b) {
965 return a.compare(b.data(), b.length()) < 0;
966}
967
973inline bool operator<=(const String &a, const String &b) {
974 return a.compare(b.data(), b.length()) <= 0;
975}
976
982inline bool operator>(const String &a, const String &b) {
983 return a.compare(b.data(), b.length()) > 0;
984}
985
991inline bool operator>=(const String &a, const String &b) {
992 return a.compare(b.data(), b.length()) >= 0;
993}
994
999inline String operator+(String a, const String &b) {
1000 a += b;
1001 return a;
1002}
1003
1005inline String operator+(String a, const char *b) {
1006 a.append(b);
1007 return a;
1008}
1009
1011inline String operator+(const char *a, const String &b) {
1012 String s1(a);
1013 s1 += b;
1014 return s1;
1015}
1016
1021inline String operator+(String a, char b) {
1022 a.append(&b, 1);
1023 return a;
1024}
1025
1026// find methods
1027
1028inline const char *rfind(const char *first, const char *last, char c) {
1029 for (const char *bb = last - 1; bb >= first; bb--)
1030 if (*bb == c)
1031 return bb;
1032 return last;
1033}
1034
1035inline const char *find(const String &s, char c) {
1036 return find(s.begin(), s.end(), c);
1037}
1038
1039
1040#if HAVE_AVX2 && !defined(CLICK_TOOL)
1041//Inspired from https://github.com/WojciechMula/sse4-strstr/
1042
1047inline const char* String::searchAVX2(const char* pattern, const int pattern_length) {
1048 //assert(k > 0);
1049 //assert(n > 0);
1050 const char* s = data();
1051 const unsigned n = length();
1052
1053 const __m256i first = _mm256_set1_epi8(pattern[0]);
1054
1055 if (unlikely(pattern_length == 1)) {
1056 for (size_t i = 0; i < n; i += 32) {
1057 const __m256i block_first = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(s + i));
1058 auto mask = _mm256_movemask_epi8(_mm256_cmpeq_epi8(first, block_first));
1059 if (mask != 0) {
1060 const auto bitpos = __builtin_ctzl(mask);
1061 return s + i + bitpos;
1062 }
1063 }
1064 }
1065
1066 const __m256i last = _mm256_set1_epi8(pattern[pattern_length - 1]);
1067
1068 for (size_t i = 0; i < n; i += 32) {
1069
1070 const __m256i block_first = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(s + i));
1071 const __m256i block_last = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(s + i + pattern_length - 1));
1072
1073 const __m256i eq_first = _mm256_cmpeq_epi8(first, block_first);
1074 const __m256i eq_last = _mm256_cmpeq_epi8(last, block_last);
1075
1076 uint32_t mask = _mm256_movemask_epi8(_mm256_and_si256(eq_first, eq_last));
1077
1078 while (mask != 0) {
1079
1080 const auto bitpos = __builtin_ctzl(mask);
1081
1082 if (memcmp(s + i + bitpos + 1, pattern + 1, pattern_length - 2) == 0) {
1083 return s + i + bitpos;
1084 }
1085
1086 mask = mask & (mask - 1);
1087 }
1088 }
1089
1090 return 0;
1091}
1092#endif
1093
1097inline const char* String::search(String pattern) {
1098 if (unlikely(length() == 0))
1099 return 0;
1100#if HAVE_AVX2 && !defined(CLICK_TOOL)
1101 return searchAVX2(pattern.data(), pattern.length());
1102#else
1103 return searchLegacy(pattern.data(), pattern.length());
1104#endif
1105}
1106
1107// sort methods
1108
1109template <typename T> int click_compare(const void *, const void *);
1110
1111template <> inline int click_compare<String>(const void *a, const void *b) {
1112 const String *ta = reinterpret_cast<const String *>(a);
1113 const String *tb = reinterpret_cast<const String *>(b);
1114 return String::compare(*ta, *tb);
1115}
1116
1117CLICK_ENDDECLS
1118#endif
An atomic 32-bit integer.
Efficiently build up Strings from pieces.
Definition straccum.hh:28
A string of characters.
Definition string.hh:22
String operator+(String a, const String &b)
Concatenate the operands and return the result.
Definition string.hh:999
void append(const String &x)
Append x to this string.
Definition string.hh:737
bool equals(const String &x) const
Test if this string equals x.
Definition string.hh:651
String printable() const
Return a "printable" version of this string.
Definition string.cc:774
String & operator=(const String &x)
Assign this string to x.
Definition string.hh:701
String upper() const
Return an uppercased version of this string.
Definition string.cc:741
char * append_uninitialized(int len)
Append len unknown characters to this string.
Definition string.cc:406
bool operator!=(const String &a, const String &b)
Compare two Strings for inequality.
Definition string.hh:945
String lower() const
Return a lowercased version of this string.
Definition string.cc:715
int find_right(char c, int start=0x7FFFFFFF) const
Search for a character in a string.
Definition string.cc:689
String compact() const
Return a compact version of this String.
Definition string.hh:830
bool operator!() const
Test if the string is empty.
Definition string.hh:599
char back() const
Return the last character in the string.
Definition string.hh:629
String substring(const char *begin, const char *end) const
Return a substring of the current string starting at first and ending before last.
Definition string.hh:550
bool starts_with(const String &x) const
Test if this string begins with prefix x.
Definition string.hh:696
bool operator<=(const String &a, const String &b)
Compare two Strings.
Definition string.hh:973
bool operator==(const String &a, const String &b)
Compares two strings for equality.
Definition string.hh:920
String trim_space_left() const
Return a substring with spaces trimmed from the start.
Definition string.cc:866
static String make_stable(const char *cstr)
Return a String that directly references the C string cstr.
Definition string.hh:463
static const char * empty_data()
Return the data pointer used for canonical empty strings.
Definition string.hh:862
String trim() const
Return a substring with spaces trimmed from both sides.
Definition string.cc:849
char at(int i) const
Return the i th character in the string.
Definition string.hh:614
void append_fill(int c, int len)
Append len copies of character c to this string.
Definition string.cc:502
bool is_stable() const
Test if the String's data is immutable.
Definition string.hh:804
String unshared() const
Return an unshared version of this String.
Definition string.hh:811
int length() const
Return the string's length.
Definition string.hh:509
String & operator+=(const String &x)
Append x to this string.
Definition string.hh:779
bool operator<(const String &a, const String &b)
Compare two Strings.
Definition string.hh:964
String encode_json() const
Return this string's contents encoded for JSON.
Definition string.cc:791
bool out_of_memory() const
Test if this is an out-of-memory string.
Definition string.hh:839
String()
Construct an empty String (with length 0).
Definition string.hh:354
const char * c_str() const
Null-terminate the string.
Definition string.hh:519
String remove(char c) const
Return a string with from replaced by to.
Definition string.cc:876
const_iterator end() const
Return an iterator for the end of the string.
Definition string.hh:584
char * mutable_data()
Ensure the string's data is unshared and return a mutable pointer to it.
Definition string.cc:512
uint32_t hashcode() const
Returns a 32-bit hash function of this string's characters.
Definition string.hh:646
String unique() const
Return an unshared version of this String.
Definition string.hh:822
static const char * skip_utf8_char(const char *first, const char *last)
Return a pointer to the next character in UTF-8 encoding.
Definition string.hh:870
static const String & make_out_of_memory()
Return a const reference to a canonical out-of-memory String.
Definition string.hh:844
String operator+(String a, char b)
Concatenate the operands and return the result.
Definition string.hh:1021
char front() const
Return the first character in the string.
Definition string.hh:622
static int compare(const String &a, const String &b)
Compare two strings.
Definition string.hh:681
void swap(String &x)
Swap the values of this string and x.
Definition string.hh:730
char * mutable_c_str()
Null-terminate the string and return a mutable pointer to its data.
Definition string.cc:552
bool operator>(const String &a, const String &b)
Compare two Strings.
Definition string.hh:982
String trim_space() const
Return a substring with spaces trimmed from the end.
Definition string.cc:856
~String()
Destroy a String, freeing memory if necessary.
Definition string.hh:432
const char * search(String pattern)
Definition string.hh:1097
static const String & make_empty()
Return a const reference to an empty String.
Definition string.hh:439
bool empty() const
Test if the string is empty.
Definition string.hh:594
static String make_uninitialized(int len)
Return a String containing len unknown characters.
Definition string.hh:444
bool glob_match(const String &pattern) const
Test whether this string matches the glob pattern.
Definition string.cc:1071
Vector< String > split(char c) const
Split a string using an input character as a delimiter. The outcome of the split is a vector of token...
Definition string.cc:625
const_iterator begin() const
Return an iterator for the first character in the string.
Definition string.hh:576
bool is_shared() const
Test if the String's data is shared or immutable.
Definition string.hh:799
int find_left(char c, int start=0) const
Search for a character in a string.
Definition string.cc:606
bool operator>=(const String &a, const String &b)
Compare two Strings.
Definition string.hh:991
static const char * out_of_memory_data()
Return the data pointer used for out-of-memory strings.
Definition string.hh:849
String quoted_hex() const
Return a hex-quoted version of the string.
Definition string.cc:922
String replace(char from, char to) const
Return a string with from replaced by to.
Definition string.cc:891
const char * data() const
Return a pointer to the string's data.
Definition string.hh:504
static String make_numeric(intmax_t x, int base=10, bool uppercase=true)
Create and return a string representation of x.
Definition string.cc:335
static int out_of_memory_length()
Return the length of canonical out-of-memory strings.
Definition string.hh:854
char operator[](int i) const
Return the i th character in the string.
Definition string.hh:606
Vector template.
Definition vector.hh:111
bool dec_and_test()
Atomically decrement the value, returning true if the new value is 0.
Definition atomic.hh:635
static void inc(volatile uint32_t &x)
Atomically increment value x.
Definition atomic.hh:304
Functions for manipulating integers.
int ffs_msb(unsigned x)
Return the index of the most significant bit set in x.
Definition integers.hh:210
Click's vector container template.