string_split_internal.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_STRINGS_STRING_SPLIT_INTERNAL_H_
  5. #define BASE_STRINGS_STRING_SPLIT_INTERNAL_H_
  6. #include <vector>
  7. #include "base/strings/string_piece.h"
  8. #include "base/strings/string_util.h"
  9. namespace base {
  10. namespace internal {
  11. // Returns either the ASCII or UTF-16 whitespace.
  12. template <typename Str>
  13. BasicStringPiece<Str> WhitespaceForType();
  14. template <>
  15. inline StringPiece16 WhitespaceForType<string16>() {
  16. return kWhitespaceUTF16;
  17. }
  18. template <>
  19. inline StringPiece WhitespaceForType<std::string>() {
  20. return kWhitespaceASCII;
  21. }
  22. // General string splitter template. Can take 8- or 16-bit input, can produce
  23. // the corresponding string or StringPiece output.
  24. template <typename OutputStringType, typename Str>
  25. static std::vector<OutputStringType> SplitStringT(
  26. BasicStringPiece<Str> str,
  27. BasicStringPiece<Str> delimiter,
  28. WhitespaceHandling whitespace,
  29. SplitResult result_type) {
  30. std::vector<OutputStringType> result;
  31. if (str.empty())
  32. return result;
  33. size_t start = 0;
  34. while (start != Str::npos) {
  35. size_t end = str.find_first_of(delimiter, start);
  36. BasicStringPiece<Str> piece;
  37. if (end == Str::npos) {
  38. piece = str.substr(start);
  39. start = Str::npos;
  40. } else {
  41. piece = str.substr(start, end - start);
  42. start = end + 1;
  43. }
  44. if (whitespace == TRIM_WHITESPACE)
  45. piece = TrimString(piece, WhitespaceForType<Str>(), TRIM_ALL);
  46. if (result_type == SPLIT_WANT_ALL || !piece.empty())
  47. result.emplace_back(piece);
  48. }
  49. return result;
  50. }
  51. template <typename OutputStringType, typename Str>
  52. std::vector<OutputStringType> SplitStringUsingSubstrT(
  53. BasicStringPiece<Str> input,
  54. BasicStringPiece<Str> delimiter,
  55. WhitespaceHandling whitespace,
  56. SplitResult result_type) {
  57. using Piece = BasicStringPiece<Str>;
  58. using size_type = typename Piece::size_type;
  59. std::vector<OutputStringType> result;
  60. if (delimiter.size() == 0) {
  61. result.emplace_back(input);
  62. return result;
  63. }
  64. for (size_type begin_index = 0, end_index = 0; end_index != Piece::npos;
  65. begin_index = end_index + delimiter.size()) {
  66. end_index = input.find(delimiter, begin_index);
  67. Piece term = end_index == Piece::npos
  68. ? input.substr(begin_index)
  69. : input.substr(begin_index, end_index - begin_index);
  70. if (whitespace == TRIM_WHITESPACE)
  71. term = TrimString(term, WhitespaceForType<Str>(), TRIM_ALL);
  72. if (result_type == SPLIT_WANT_ALL || !term.empty())
  73. result.emplace_back(term);
  74. }
  75. return result;
  76. }
  77. } // namespace internal
  78. } // namespace base
  79. #endif // BASE_STRINGS_STRING_SPLIT_INTERNAL_H_