libfilezilla
string.hpp
Go to the documentation of this file.
1 #ifndef LIBFILEZILLA_STRING_HEADER
2 #define LIBFILEZILLA_STRING_HEADER
3 
4 #include "libfilezilla.hpp"
5 
6 #include <algorithm>
7 #include <cstdint>
8 #include <limits>
9 #include <optional>
10 #include <string>
11 #include <string_view>
12 #include <vector>
13 
14 template<class CharT, class BaseT>
16 {
17 public:
18  using char_type = CharT;
19 
20  using base_type = BaseT;
21  using base_traits = std::char_traits<base_type>;
22 
23  static std::size_t length(char_type const* s) {
24  return base_traits::length(reinterpret_cast<base_type const*>(s));
25  }
26  static int compare(char_type const* s1, char_type const* s2, std::size_t count) {
27  return base_traits::compare(reinterpret_cast<base_type const*>(s1), reinterpret_cast<base_type const*>(s2), count);
28  }
29  static char_type* copy(char_type* dest, char_type const* src, std::size_t count) {
30  return reinterpret_cast<char_type*>(base_traits::copy(reinterpret_cast<base_type*>(dest), reinterpret_cast<base_type const*>(src), count));
31  }
32  static void assign( char_type& c1, char_type const& c2 ) noexcept {
33  c1 = c2;
34  }
35  static char_type const* find(char_type const* ptr, std::size_t count, char_type const& ch) {
36  return reinterpret_cast<char_type const*>(base_traits::find(reinterpret_cast<base_type const*>(ptr), count, reinterpret_cast<base_type const&>(ch)));
37  }
38  static bool eq(char_type a, char_type b) {
39  return base_traits::eq(static_cast<base_type>(a), static_cast<base_type>(b));
40  }
41 };
42 
43 template<>
44 class std::char_traits<uint8_t> : public traits_cloner<uint8_t, char>
45 {};
46 
54 namespace fz {
55 
68 #ifdef FZ_WINDOWS
69 typedef std::wstring native_string;
70 typedef std::wstring_view native_string_view;
71 #endif
72 #if defined(FZ_UNIX) || defined(FZ_MAC)
73 typedef std::string native_string;
74 typedef std::string_view native_string_view;
75 #endif
76 
81 native_string FZ_PUBLIC_SYMBOL to_native(std::string_view const& in);
82 
87 native_string FZ_PUBLIC_SYMBOL to_native(std::wstring_view const& in);
88 
90 template<typename T, typename std::enable_if_t<std::is_same_v<native_string, typename std::decay_t<T>>, int> = 0>
91 inline native_string to_native(T const& in) {
92  return in;
93 }
94 
101 int FZ_PUBLIC_SYMBOL stricmp(std::string_view const& a, std::string_view const& b);
102 int FZ_PUBLIC_SYMBOL stricmp(std::wstring_view const& a, std::wstring_view const& b);
103 
121 template<typename Char>
122 Char tolower_ascii(Char c) {
123  if (c >= 'A' && c <= 'Z') {
124  return c + ('a' - 'A');
125  }
126  return c;
127 }
128 
129 template<>
130 std::wstring::value_type FZ_PUBLIC_SYMBOL tolower_ascii(std::wstring::value_type c);
131 
133 template<typename Char>
134 Char toupper_ascii(Char c) {
135  if (c >= 'a' && c <= 'z') {
136  return c + ('A' - 'a');
137  }
138  return c;
139 }
140 
141 template<>
142 std::wstring::value_type FZ_PUBLIC_SYMBOL toupper_ascii(std::wstring::value_type c);
143 
146  // Note: For UTF-8 strings it works on individual octets!
147 std::string FZ_PUBLIC_SYMBOL str_tolower_ascii(std::string_view const& s);
148 std::wstring FZ_PUBLIC_SYMBOL str_tolower_ascii(std::wstring_view const& s);
149 
150 std::string FZ_PUBLIC_SYMBOL str_toupper_ascii(std::string_view const& s);
151 std::wstring FZ_PUBLIC_SYMBOL str_toupper_ascii(std::wstring_view const& s);
152 
155 template<typename T, typename = void>
157 
158 template<typename T>
159 struct string_value_type<T, std::void_t<typename T::value_type>> {
160  using type = typename T::value_type;
161 };
162 
163 template<typename CharT>
164 struct string_value_type<CharT*> {
165  using type = std::remove_cv_t<CharT>;
166 };
167 
168 template<typename CharT, std::size_t N>
169 struct string_value_type<CharT (&)[N]> {
170  using type = std::remove_cv_t<CharT>;
171 };
172 
173 template<typename CharT, std::size_t N>
174 struct string_value_type<CharT[N]> {
175  using type = std::remove_cv_t<CharT>;
176 };
177 
178 // Helper alias for easier use.
179 template<typename T>
180 using string_value_type_t = typename string_value_type<T>::type;
181 
187 struct FZ_PUBLIC_SYMBOL less_insensitive_ascii final
188 {
189  using is_transparent = std::true_type;
190 
191  template<typename L, typename R,
192  std::enable_if_t<std::is_same_v<string_value_type_t<L>, string_value_type_t<R>>>* = nullptr>
193  bool operator()(L const& lhs, R const& rhs) const {
194  std::basic_string_view<string_value_type_t<L>> lv(lhs);
195  std::basic_string_view<string_value_type_t<R>> rv(rhs);
196 
197  return std::lexicographical_compare(lv.begin(), lv.end(), rv.begin(), rv.end(),
198  [](auto const& a, auto const& b) {
199  return tolower_ascii(a) < tolower_ascii(b);
200  }
201  );
202  }
203 };
204 
209 template<typename A, typename B,
210  std::enable_if_t<std::is_same_v<string_value_type_t<A>, string_value_type_t<B>>>* = nullptr>
211 inline bool equal_insensitive_ascii(A const& a, B const& b)
212 {
213  std::basic_string_view<string_value_type_t<A>> av(a);
214  std::basic_string_view<string_value_type_t<B>> bv(b);
215 
216  return std::equal(av.cbegin(), av.cend(), bv.cbegin(), bv.cend(),
217  [](auto const& a, auto const& b) {
218  return tolower_ascii(a) == tolower_ascii(b);
219  }
220  );
221 }
222 
227 std::wstring FZ_PUBLIC_SYMBOL to_wstring(std::string_view const& in);
228 
233 template <typename T>
234 inline auto to_wstring(T && in) -> decltype(std::wstring(std::forward<T>(in)))
235 {
236  return std::wstring(std::forward<T>(in));
237 }
238 
240 template<typename Arg>
241 inline typename std::enable_if<std::is_arithmetic_v<std::decay_t<Arg>>, std::wstring>::type to_wstring(Arg && arg)
242 {
243  return std::to_wstring(std::forward<Arg>(arg));
244 }
245 
246 
251 std::wstring FZ_PUBLIC_SYMBOL to_wstring_from_utf8(std::string_view const& in);
252 std::wstring FZ_PUBLIC_SYMBOL to_wstring_from_utf8(char const* s, size_t len);
253 
254 class buffer;
255 std::wstring FZ_PUBLIC_SYMBOL to_wstring_from_utf8(fz::buffer const& in);
256 
261 std::string FZ_PUBLIC_SYMBOL to_string(std::wstring_view const& in);
262 
267 template <typename T>
268 inline auto to_string(T && in) -> decltype(std::string(std::forward<T>(in)))
269 {
270  return std::string(std::forward<T>(in));
271 }
272 
273 
275 template<typename Arg>
276 inline typename std::enable_if<std::is_arithmetic_v<std::decay_t<Arg>>, std::string>::type to_string(Arg && arg)
277 {
278  return std::to_string(std::forward<Arg>(arg));
279 }
280 
281 
283 template<typename Char>
284 size_t strlen(Char const* str) {
285  return std::char_traits<Char>::length(str);
286 }
287 
288 
295 std::string FZ_PUBLIC_SYMBOL to_utf8(std::string_view const& in);
296 
303 std::string FZ_PUBLIC_SYMBOL to_utf8(std::wstring_view const& in);
304 
306 template<typename String, typename Arg>
307 inline auto toString(Arg&& arg) -> typename std::enable_if<std::is_same_v<String, std::string>, decltype(to_string(std::forward<Arg>(arg)))>::type
308 {
309  return to_string(std::forward<Arg>(arg));
310 }
311 
312 template<typename String, typename Arg>
313 inline auto toString(Arg&& arg) -> typename std::enable_if<std::is_same_v<String, std::wstring>, decltype(to_wstring(std::forward<Arg>(arg)))>::type
314 {
315  return to_wstring(std::forward<Arg>(arg));
316 }
317 
318 #if !defined(fzT) || defined(DOXYGEN)
319 #ifdef FZ_WINDOWS
320 
324 #define fzT(x) L ## x
325 #else
326 
330 #define fzT(x) x
331 #endif
332 #endif
333 
335 template<typename Char>
336 constexpr Char const* choose_string(char const* c, wchar_t const* w);
337 
338 template<> constexpr inline char const* choose_string(char const* c, wchar_t const*) { return c; }
339 template<> constexpr inline wchar_t const* choose_string(char const*, wchar_t const* w) { return w; }
340 
341 #if !defined(fzS) || defined(DOXYGEN)
342 
353 #define fzS(Char, s) fz::choose_string<Char>(s, L ## s)
354 #endif
355 
360 std::string FZ_PUBLIC_SYMBOL replaced_substrings(std::string_view const& in, std::string_view const& find, std::string_view const& replacement);
361 std::wstring FZ_PUBLIC_SYMBOL replaced_substrings(std::wstring_view const& in, std::wstring_view const& find, std::wstring_view const& replacement);
362 
364 std::string FZ_PUBLIC_SYMBOL replaced_substrings(std::string_view const& in, char find, char replacement);
365 std::wstring FZ_PUBLIC_SYMBOL replaced_substrings(std::wstring_view const& in, wchar_t find, wchar_t replacement);
366 
371 bool FZ_PUBLIC_SYMBOL replace_substrings(std::string& in, std::string_view const& find, std::string_view const& replacement);
372 bool FZ_PUBLIC_SYMBOL replace_substrings(std::wstring& in, std::wstring_view const& find, std::wstring_view const& replacement);
373 
375 bool FZ_PUBLIC_SYMBOL replace_substrings(std::string& in, char find, char replacement);
376 bool FZ_PUBLIC_SYMBOL replace_substrings(std::wstring& in, wchar_t find, wchar_t replacement);
377 
378 namespace detail {
380 template <typename T>
381 struct operator_arrow_proxy
382 {
383  T v_;
384 
385  T* operator->() { return &v_; }
386 };
387 
388 template <typename T>
389 struct operator_arrow_proxy<const T>
390 {
391  T v_;
392 
393  T* operator->() const { return &v_; }
394 };
395 
396 }
397 
424 template <typename String, typename Delims>
426 {
427  using view_type = std::basic_string_view<std::decay_t<decltype(std::declval<String>()[0])>>;
428 
429 public:
436  constexpr strtokenizer(String && string, Delims &&delims, bool ignore_empty)
437  : string_(std::forward<String>(string))
438  , delims_(std::forward<Delims>(delims))
439  , ignore_empty_(ignore_empty)
440  {}
441 
442  using value_type = const view_type;
443  using pointer = detail::operator_arrow_proxy<value_type>;
444  using reference = value_type&;
445  using size_type = std::size_t;
446  using difference_type = std::ptrdiff_t;
447 
448  struct iterator
449  {
450  using iterator_category = std::forward_iterator_tag;
451  using difference_type = strtokenizer::difference_type;
452  using value_type = strtokenizer::value_type;
453  using pointer = strtokenizer::pointer;
454  using reference = strtokenizer::reference;
455 
456  constexpr bool operator ==(iterator const& op) const
457  {
458  return s_.size() == op.s_.size();
459  }
460 
461  constexpr bool operator !=(iterator const& op) const
462  {
463  return s_.size() != op.s_.size();
464  }
465 
466  constexpr value_type operator*() const
467  {
468  return s_.substr(0, pos_);
469  }
470 
471  constexpr pointer operator->() const
472  {
473  return { s_.substr(0, pos_) };
474  }
475 
476  constexpr iterator &operator++()
477  {
478  for (;;) {
479  if (pos_ != s_.size()) {
480  ++pos_;
481  }
482 
483  s_.remove_prefix(pos_);
484 
485  pos_ = s_.find_first_of(t_->delims_);
486 
487  if (pos_ == view_type::npos) {
488  pos_ = s_.size();
489  break;
490  }
491 
492  if (pos_ != 0 || !t_->ignore_empty_) {
493  break;
494  }
495  }
496 
497  return *this;
498  }
499 
500  constexpr iterator operator++(int)
501  {
502  iterator copy(*this);
503  operator++();
504  return copy;
505  }
506 
507  constexpr iterator() = default;
508 
509  private:
510  friend strtokenizer;
511 
512  constexpr iterator(const strtokenizer *t)
513  : t_(t)
514  , s_(view_type(t_->string_))
515  {
516  operator++();
517  }
518 
519  const strtokenizer *t_{};
520  view_type s_{};
521  size_type pos_{view_type::npos};
522  };
523 
524  using const_iterator = iterator;
525 
526  constexpr iterator begin() const
527  {
528  return { this };
529  }
530 
531  constexpr iterator end() const
532  {
533  return {};
534  }
535 
536  constexpr const_iterator cbegin() const
537  {
538  return { this };
539  }
540 
541  constexpr const_iterator cend() const
542  {
543  return {};
544  }
545 
546 public:
547  String string_;
548  Delims delims_;
549  bool ignore_empty_;
550 };
551 
558 template <typename String, typename Delims>
559 strtokenizer(String && string, Delims &&delims, bool ignore_empty) -> strtokenizer<String, Delims>;
560 
564 template <typename LhsString, typename LhsDelims, typename RhsString, typename RhsDelims>
565 bool operator<(strtokenizer<LhsString, LhsDelims> const &lhs, strtokenizer<RhsString, RhsDelims> const &rhs)
566 {
567  return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
568 }
569 
573 template <typename LhsString, typename LhsDelims, typename RhsString, typename RhsDelims>
575 {
576  return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
577 }
578 
585 std::vector<std::string> FZ_PUBLIC_SYMBOL strtok(std::string_view const& tokens, std::string_view const& delims, bool const ignore_empty = true);
586 std::vector<std::wstring> FZ_PUBLIC_SYMBOL strtok(std::wstring_view const& tokens, std::wstring_view const& delims, bool const ignore_empty = true);
587 inline auto strtok(std::string_view const& tokens, char const delim, bool const ignore_empty = true) {
588  return strtok(tokens, std::string_view(&delim, 1), ignore_empty);
589 }
590 inline auto strtok(std::wstring_view const& tokens, wchar_t const delim, bool const ignore_empty = true) {
591  return strtok(tokens, std::wstring_view(&delim, 1), ignore_empty);
592 }
593 
602 std::vector<std::string_view> FZ_PUBLIC_SYMBOL strtok_view(std::string_view const& tokens, std::string_view const& delims, bool const ignore_empty = true);
603 std::vector<std::wstring_view> FZ_PUBLIC_SYMBOL strtok_view(std::wstring_view const& tokens, std::wstring_view const& delims, bool const ignore_empty = true);
604 inline auto strtok_view(std::string_view const& tokens, char const delim, bool const ignore_empty = true) {
605  return strtok_view(tokens, std::string_view(&delim, 1), ignore_empty);
606 }
607 inline auto strtok_view(std::wstring_view const& tokens, wchar_t const delim, bool const ignore_empty = true) {
608  return strtok_view(tokens, std::wstring_view(&delim, 1), ignore_empty);
609 }
610 
612 template<typename T, typename String>
613 bool to_integral_impl(String const& s, T & v)
614 {
615  if constexpr (std::is_same_v<T, bool>) {
616  unsigned int w{};
617  if (!to_integral_impl(s, w)) {
618  return false;
619  }
620  v = w != 0;
621  return true;
622  }
623  else if constexpr (std::is_enum_v<T>) {
624  return to_integral_impl<std::underlying_type_t<T>>(s, reinterpret_cast<std::underlying_type_t<T>&>(v));
625  }
626  else {
627  bool negative{};
628 
629  auto it = s.cbegin();
630  if (it != s.cend() && (*it == '-' || *it == '+')) {
631  if (*it == '-') {
632  if constexpr (std::is_signed_v<T>) {
633  negative = true;
634  }
635  else {
636  return false;
637  }
638  }
639  ++it;
640  }
641 
642  if (it == s.cend()) {
643  return false;
644  }
645 
646  v = T{};
647  if (negative) {
648  auto constexpr min = std::numeric_limits<T>::min();
649  auto constexpr min10 = min / 10;
650  for (; it != s.cend(); ++it) {
651  auto const& c = *it;
652  if (c < '0' || c > '9') {
653  return false;
654  }
655  if (v < min10) {
656  return false;
657  }
658  v *= 10;
659  auto digit = -static_cast<T>(c - '0');
660  if (min - v > digit) {
661  return false;
662  }
663  v += digit;
664  }
665  }
666  else {
667  auto constexpr max = std::numeric_limits<T>::max();
668  auto constexpr max10 = max / 10;
669  for (; it != s.cend(); ++it) {
670  auto const& c = *it;
671  if (c < '0' || c > '9') {
672  return false;
673  }
674  if (v > max10) {
675  return false;
676  }
677  v *= 10;
678  auto digit = static_cast<T>(c - '0');
679  if (max - v < digit) {
680  return false;
681  }
682  v += digit;
683  }
684  }
685  }
686  return true;
687 }
688 
690 template<typename T>
691 T to_integral(std::string_view const& s, T const errorval = T()) {
692  T out{};
693  if (!to_integral_impl<T>(s, out)) {
694  out = errorval;
695  }
696  return out;
697 }
698 
699 template<typename T>
700 T to_integral(std::wstring_view const& s, T const errorval = T()) {
701  T out{};
702  if (!to_integral_impl<T>(s, out)) {
703  out = errorval;
704  }
705  return out;
706 }
707 
708 template<typename T, typename StringType>
709 T to_integral(std::basic_string_view<StringType> const& s, T const errorval = T()) {
710  T out{};
711  if (!to_integral_impl<T>(s, out)) {
712  out = errorval;
713  }
714  return out;
715 }
716 
718 template<typename T>
719 std::optional<T> to_integral_o(std::string_view const& s) {
720  std::optional<T> ret;
721  T out{};
722  if (to_integral_impl<T>(s, out)) {
723  ret = out;
724  }
725  return ret;
726 }
727 
728 template<typename T>
729 std::optional<T> to_integral_o(std::wstring_view const& s) {
730  std::optional<T> ret;
731  T out{};
732  if (to_integral_impl<T>(s, out)) {
733  ret = out;
734  }
735  return ret;
736 }
737 
738 template<typename T, typename StringType>
739 std::optional<T> to_integral_o(std::basic_string_view<StringType> const& s) {
740  std::optional<T> ret;
741  T out{};
742  if (to_integral_impl<T>(s, out)) {
743  ret = out;
744  }
745  return ret;
746 }
747 
748 
750 template<typename String>
751 bool str_is_ascii(String const& s) {
752  for (auto const& c : s) {
753  if (static_cast<std::make_unsigned_t<typename String::value_type>>(c) > 127) {
754  return false;
755  }
756  }
757 
758  return true;
759 }
760 
762 template<typename String, typename Chars>
763 void trim_impl(String & s, Chars const& chars, bool fromLeft, bool fromRight) {
764  size_t const first = fromLeft ? s.find_first_not_of(chars) : 0;
765  if (first == String::npos) {
766  s = String();
767  return;
768  }
769 
770  size_t const last = fromRight ? s.find_last_not_of(chars) : s.size();
771  if (last == String::npos) {
772  s = String();
773  return;
774  }
775 
776  // Invariant: If first exists, then last >= first
777  s = s.substr(first, last - first + 1);
778 }
779 
781 inline std::string trimmed(std::string_view s, std::string_view const& chars = " \r\n\t", bool fromLeft = true, bool fromRight = true)
782 {
783  trim_impl(s, chars, fromLeft, fromRight);
784  return std::string(s);
785 }
786 
787 inline std::wstring trimmed(std::wstring_view s, std::wstring_view const& chars = L" \r\n\t", bool fromLeft = true, bool fromRight = true)
788 {
789  trim_impl(s, chars, fromLeft, fromRight);
790  return std::wstring(s);
791 }
792 
793 inline std::string ltrimmed(std::string_view s, std::string_view const& chars = " \r\n\t")
794 {
795  trim_impl(s, chars, true, false);
796  return std::string(s);
797 }
798 
799 inline std::wstring ltrimmed(std::wstring_view s, std::wstring_view const& chars = L" \r\n\t")
800 {
801  trim_impl(s, chars, true, false);
802  return std::wstring(s);
803 }
804 
805 inline std::string rtrimmed(std::string_view s, std::string_view const& chars = " \r\n\t")
806 {
807  trim_impl(s, chars, false, true);
808  return std::string(s);
809 }
810 
811 inline std::wstring rtrimmed(std::wstring_view s, std::wstring_view const& chars = L" \r\n\t")
812 {
813  trim_impl(s, chars, false, true);
814  return std::wstring(s);
815 }
816 
817 
819 template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, char>, int> = 0>
820 inline void trim(String & s, std::string_view const& chars = " \r\n\t", bool fromLeft = true, bool fromRight = true)
821 {
822  trim_impl(s, chars, fromLeft, fromRight);
823 }
824 
825 template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, wchar_t>, int> = 0>
826 inline void trim(String & s, std::wstring_view const& chars = L" \r\n\t", bool fromLeft = true, bool fromRight = true)
827 {
828  trim_impl(s, chars, fromLeft, fromRight);
829 }
830 
831 template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, char>, int> = 0>
832 inline void ltrim(String& s, std::string_view const& chars = " \r\n\t")
833 {
834  trim_impl(s, chars, true, false);
835 }
836 
837 template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, wchar_t>, int> = 0>
838 inline void ltrim(String& s, std::wstring_view const& chars = L" \r\n\t")
839 {
840  trim_impl(s, chars, true, false);
841 }
842 
843 template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, char>, int> = 0>
844 inline void rtrim(String& s, std::string_view const& chars = " \r\n\t")
845 {
846  trim_impl(s, chars, false, true);
847 }
848 
849 template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, wchar_t>, int> = 0>
850 inline void rtrim(String & s, std::wstring_view const& chars = L" \r\n\t")
851 {
852  trim_impl(s, chars, false, true);
853 }
854 
859 template<bool insensitive_ascii = false, typename String, typename Beginning>
860  std::enable_if_t<std::is_same_v<string_value_type_t<String>, string_value_type_t<Beginning>>,
861 bool> starts_with(String const& s, Beginning const& beginning)
862 {
863  std::basic_string_view<string_value_type_t<String>> sv(s);
864  std::basic_string_view<string_value_type_t<Beginning>> beginningv(beginning);
865 
866  if (beginningv.size() > sv.size()) {
867  return false;
868  }
869 
870  if constexpr (insensitive_ascii) {
871  return std::equal(beginningv.begin(), beginningv.end(), sv.begin(), [](auto const& a, auto const& b) {
872  return tolower_ascii(a) == tolower_ascii(b);
873  });
874  } else {
875  return std::equal(beginningv.begin(), beginningv.end(), sv.begin());
876  }
877 }
878 
883 template<bool insensitive_ascii = false, typename String, typename Ending>
884  std::enable_if_t<std::is_same_v<string_value_type_t<String>, string_value_type_t<Ending>>,
885 bool> ends_with(String const& s, Ending const& ending)
886 {
887  std::basic_string_view<string_value_type_t<String>> sv(s);
888  std::basic_string_view<string_value_type_t<Ending>> endingv(ending);
889 
890  if (endingv.size() > sv.size()) {
891  return false;
892  }
893 
894  if constexpr (insensitive_ascii) {
895  return std::equal(endingv.rbegin(), endingv.rend(), sv.rbegin(), [](auto const& a, auto const& b) {
896  return tolower_ascii(a) == tolower_ascii(b);
897  });
898  }
899  else {
900  return std::equal(endingv.rbegin(), endingv.rend(), sv.rbegin());
901  }
902 }
903 
909 std::string FZ_PUBLIC_SYMBOL normalize_hyphens(std::string_view const& in);
910 std::wstring FZ_PUBLIC_SYMBOL normalize_hyphens(std::wstring_view const& in);
911 
913 bool FZ_PUBLIC_SYMBOL is_valid_utf8(std::string_view s);
914 
935 bool FZ_PUBLIC_SYMBOL is_valid_utf8(std::string_view s, size_t & state);
936 
942 void FZ_PUBLIC_SYMBOL unicode_codepoint_to_utf8_append(std::string& result, uint32_t codepoint);
943 
964 bool FZ_PUBLIC_SYMBOL utf16be_to_utf8_append(std::string & result, std::string_view data, uint32_t & state);
965 
967 bool FZ_PUBLIC_SYMBOL utf16le_to_utf8_append(std::string & result, std::string_view data, uint32_t & state);
968 
969 inline native_string to_native_from_utf8(std::string_view s) {
970 #ifdef FZ_WINDOWS
971  return to_wstring_from_utf8(s);
972 #else
973  return to_string(to_wstring_from_utf8(s));
974 #endif
975 }
976 
977 FZ_PUBLIC_SYMBOL void wipe_conversion_cache();
978 
979 }
980 
981 #endif
bool is_valid_utf8(std::string_view s)
Verifies that the input data is valid UTF-8.
std::enable_if_t< std::is_same_v< string_value_type_t< String >, string_value_type_t< Beginning > >, bool > starts_with(String const &s, Beginning const &beginning)
Tests whether the first string starts with the second string.
Definition: string.hpp:861
auto toString(Arg &&arg) -> typename std::enable_if< std::is_same_v< String, std::string >, decltype(to_string(std::forward< Arg >(arg)))>::type
Calls either fz::to_string or fz::to_wstring depending on the passed template argument.
Definition: string.hpp:307
T to_integral(std::string_view const &s, T const errorval=T())
Converts string to integral type T. If string is not convertible, errorval is returned.
Definition: string.hpp:691
Comparator to be used for std::map for case-insensitive keys.
Definition: string.hpp:187
bool replace_substrings(std::string &in, std::string_view const &find, std::string_view const &replacement)
Modifies in, replacing all occurrences of find with replacement.
std::wstring to_wstring(std::string_view const &in)
Converts from std::string in system encoding into std::wstring.
bool operator==(symmetric_key const &lhs, symmetric_key const &rhs)
Side-channel safe comparison.
Char toupper_ascii(Char c)
Converts ASCII lowercase characters to uppercase as if C-locale is used.
Definition: string.hpp:134
Container-like class that can be used to iterate over tokens in a string.
Definition: string.hpp:425
native_string to_native(std::string_view const &in)
Converts std::string to native_string.
bool equal_insensitive_ascii(A const &a, B const &b)
Locale-insensitive stricmp.
Definition: string.hpp:211
std::string to_utf8(std::string_view const &in)
Converts from std::string in native encoding into std::string in UTF-8.
A type trait to identify the value_type of any string-like type.
Definition: string.hpp:156
Definition: impersonation.hpp:100
std::vector< std::string_view > strtok_view(std::string_view const &tokens, std::string_view const &delims, bool const ignore_empty=true)
Tokenizes string.
std::string trimmed(std::string_view s, std::string_view const &chars=" \r\n\t", bool fromLeft=true, bool fromRight=true)
Return passed string with all leading and trailing whitespace removed.
Definition: string.hpp:781
std::string replaced_substrings(std::string_view const &in, std::string_view const &find, std::string_view const &replacement)
Returns in with all occurrences of find in the input string replaced with replacement.
Char tolower_ascii(Char c)
Converts ASCII uppercase characters to lowercase as if C-locale is used.
Definition: string.hpp:122
constexpr strtokenizer(String &&string, Delims &&delims, bool ignore_empty)
strtokenizer class constructor.
Definition: string.hpp:436
Definition: string.hpp:448
constexpr Char const * choose_string(char const *c, wchar_t const *w)
Returns the function argument of the type matching the template argument.
Definition: string.hpp:338
std::enable_if< std::is_arithmetic_v< std::decay_t< Arg > >, std::string >::type to_string(Arg &&arg)
Converts from arithmetic type to std::string.
Definition: string.hpp:276
std::wstring to_wstring_from_utf8(std::string_view const &in)
Converts from std::string in UTF-8 into std::wstring.
size_t strlen(Char const *str)
Returns length of 0-terminated character sequence. Works with both narrow and wide-characters.
Definition: string.hpp:284
std::string normalize_hyphens(std::string_view const &in)
bool str_is_ascii(String const &s)
Returns true iff the string only has characters in the 7-bit ASCII range.
Definition: string.hpp:751
std::string str_tolower_ascii(std::string_view const &s)
tr_tolower_ascii does for strings what tolower_ascii does for individual characters ...
std::enable_if_t< std::is_same_v< string_value_type_t< String >, string_value_type_t< Ending > >, bool > ends_with(String const &s, Ending const &ending)
Tests whether the first string ends with the second string.
Definition: string.hpp:885
std::wstring native_string
A string in the system's native character type and encoding. Note: This typedef changes depending on...
Definition: string.hpp:69
Definition: string.hpp:15
void trim(String &s, std::string_view const &chars=" \r\n\t", bool fromLeft=true, bool fromRight=true)
Remove all leading and trailing whitespace from string.
Definition: string.hpp:820
The namespace used by libfilezilla.
Definition: apply.hpp:17
strtokenizer(String &&string, Delims &&delims, bool ignore_empty) -> strtokenizer< String, Delims >
strtokenizer class construction-guide.
std::optional< T > to_integral_o(std::string_view const &s)
Converts string to integral type T. If string is not convertible, nullopt.
Definition: string.hpp:719
std::vector< std::string > strtok(std::string_view const &tokens, std::string_view const &delims, bool const ignore_empty=true)
Tokenizes string.
Sets some global macros and further includes string.hpp.
int stricmp(std::string_view const &a, std::string_view const &b)
Locale-sensitive stricmp.
bool utf16be_to_utf8_append(std::string &result, std::string_view data, uint32_t &state)
Converts from UTF-16-BE and appends it to the passed string.
The buffer class is a simple buffer where data can be appended at the end and consumed at the front...
Definition: buffer.hpp:26
std::enable_if< std::is_arithmetic_v< std::decay_t< Arg > >, std::wstring >::type to_wstring(Arg &&arg)
Converts from arithmetic type to std::wstring.
Definition: string.hpp:241
void unicode_codepoint_to_utf8_append(std::string &result, uint32_t codepoint)
Encodes a valid Unicode codepoint as UTF-8 and appends it to the passed string.
bool utf16le_to_utf8_append(std::string &result, std::string_view data, uint32_t &state)
Just as utf16be_to_utf8_append but for little-endian UTF-16.
std::string to_string(std::wstring_view const &in)
Converts from std::wstring into std::string in system encoding.