123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- #pragma once
- // THIS FILE A COMPAT STUB HEADER
- #include <cstring>
- #include <cstdarg>
- #include <algorithm>
- #include <util/system/defaults.h>
- #include <util/generic/string.h>
- #include <util/generic/strbuf.h>
- /// @addtogroup Strings_Miscellaneous
- /// @{
- int a2i(const TString& s);
- /// Removes the last character if it is equal to c.
- template <class T>
- inline void RemoveIfLast(T& s, int c) {
- const size_t length = s.length();
- if (length && s[length - 1] == c)
- s.remove(length - 1);
- }
- /// Adds lastCh symbol to the the of the string if it is not already there.
- inline void addIfNotLast(TString& s, int lastCh) {
- size_t len = s.length();
- if (!len || s[len - 1] != lastCh) {
- s.append(char(lastCh));
- }
- }
- /// @details Finishes the string with lastCh1 if lastCh2 is not present in the string and lastCh1 is not already at the end of the string.
- /// Else, if lastCh2 is not equal to the symbol before the last, it finishes the string with lastCh2.
- /// @todo ?? Define, when to apply the function. Is in use several times for URLs parsing.
- inline void addIfAbsent(TString& s, char lastCh1, char lastCh2) {
- size_t pos = s.find(lastCh2);
- if (pos == TString::npos) {
- // s.append((char)lastCh1);
- addIfNotLast(s, lastCh1);
- } else if (pos < s.length() - 1) {
- addIfNotLast(s, lastCh2);
- }
- }
- /// @}
- /*
- * ------------------------------------------------------------------
- *
- * A fast implementation of glibc's functions;
- * strspn, strcspn and strpbrk.
- *
- * ------------------------------------------------------------------
- */
- struct ui8_256 {
- // forward chars table
- ui8 chars_table[256];
- // reverse (for c* functions) chars table
- ui8 c_chars_table[256];
- };
- class str_spn: public ui8_256 {
- public:
- explicit str_spn(const char* charset, bool extended = false) {
- // exteneded: if true, treat charset string more like
- // interior of brackets [ ], e.g. "a-z0-9"
- init(charset, extended);
- }
- /// Return first character in table, like strpbrk()
- /// That is, skip all characters not in table
- /// [DIFFERENCE FOR NOT_FOUND CASE: Returns end of string, not NULL]
- const char* brk(const char* s) const {
- while (c_chars_table[(ui8)*s])
- ++s;
- return s;
- }
- const char* brk(const char* s, const char* e) const {
- while (s < e && c_chars_table[(ui8)*s])
- ++s;
- return s;
- }
- /// Return first character not in table, like strpbrk() for inverted table.
- /// That is, skip all characters in table
- const char* cbrk(const char* s) const {
- while (chars_table[(ui8)*s])
- ++s;
- return s;
- }
- const char* cbrk(const char* s, const char* e) const {
- while (s < e && chars_table[(ui8)*s])
- ++s;
- return s;
- }
- /// Offset of the first character not in table, like strspn().
- size_t spn(const char* s) const {
- return cbrk(s) - s;
- }
- size_t spn(const char* s, const char* e) const {
- return cbrk(s, e) - s;
- }
- /// Offset of the first character in table, like strcspn().
- size_t cspn(const char* s) const {
- return brk(s) - s;
- }
- size_t cspn(const char* s, const char* e) const {
- return brk(s, e) - s;
- }
- char* brk(char* s) const {
- return const_cast<char*>(brk((const char*)s));
- }
- char* cbrk(char* s) const {
- return const_cast<char*>(cbrk((const char*)s));
- }
- /// See strsep [BUT argument is *&, not **]
- char* sep(char*& s) const {
- char sep_char; // unused;
- return sep(s, sep_char);
- }
- /// strsep + remember character that was destroyed
- char* sep(char*& s, char& sep_char) const {
- if (!s)
- return nullptr;
- char* ret = s;
- char* next = brk(ret);
- if (*next) {
- sep_char = *next;
- *next = 0;
- s = next + 1;
- } else {
- sep_char = 0;
- s = nullptr;
- }
- return ret;
- }
- protected:
- void init(const char* charset, bool extended);
- str_spn() = default;
- };
- // an analogue of tr/$from/$to/
- class Tr {
- public:
- Tr(const char* from, const char* to);
- char ConvertChar(char ch) const {
- return Map[(ui8)ch];
- }
- void Do(char* s) const {
- for (; *s; s++)
- *s = ConvertChar(*s);
- }
- void Do(const char* src, char* dst) const {
- for (; *src; src++)
- *dst++ = ConvertChar(*src);
- *dst = 0;
- }
- void Do(char* s, size_t l) const {
- for (size_t i = 0; i < l && s[i]; i++)
- s[i] = ConvertChar(s[i]);
- }
- void Do(TString& str) const;
- private:
- char Map[256];
- size_t FindFirstChangePosition(const TString& str) const;
- };
- // Removes all occurrences of given character from string
- template <typename TStringType>
- void RemoveAll(TStringType& str, typename TStringType::char_type ch) {
- size_t pos = str.find(ch); // 'find' to avoid cloning of string in 'TString.begin()'
- if (pos == TStringType::npos)
- return;
- typename TStringType::iterator begin = str.begin();
- typename TStringType::iterator end = begin + str.length();
- typename TStringType::iterator it = std::remove(begin + pos, end, ch);
- str.erase(it, end);
- }
|