char_iterator.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Copyright (c) 2011 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_I18N_CHAR_ITERATOR_H_
  5. #define BASE_I18N_CHAR_ITERATOR_H_
  6. #include <stdint.h>
  7. #include "base/i18n/base_i18n_export.h"
  8. #include "base/strings/string_piece.h"
  9. // The CharIterator classes iterate through the characters in UTF8 and
  10. // UTF16 strings. Example usage:
  11. //
  12. // for (UTF8CharIterator iter(str); !iter.end(); iter.Advance()) {
  13. // VLOG(1) << iter.get();
  14. // }
  15. namespace base {
  16. namespace i18n {
  17. class BASE_I18N_EXPORT UTF8CharIterator {
  18. public:
  19. // Requires |str| to live as long as the UTF8CharIterator does.
  20. explicit UTF8CharIterator(StringPiece str);
  21. UTF8CharIterator(const UTF8CharIterator&) = delete;
  22. UTF8CharIterator& operator=(const UTF8CharIterator&) = delete;
  23. ~UTF8CharIterator();
  24. // Return the starting array index of the current character within the
  25. // string.
  26. size_t array_pos() const { return array_pos_; }
  27. // Return the logical index of the current character, independent of the
  28. // number of bytes each character takes.
  29. size_t char_pos() const { return char_pos_; }
  30. // Return the current char.
  31. int32_t get() const { return char_; }
  32. // Returns true if we're at the end of the string.
  33. bool end() const { return array_pos_ == str_.length(); }
  34. // Advance to the next actual character. Returns false if we're at the
  35. // end of the string.
  36. bool Advance();
  37. private:
  38. // The string we're iterating over.
  39. StringPiece str_;
  40. // Array index.
  41. size_t array_pos_;
  42. // The next array index.
  43. size_t next_pos_;
  44. // Character index.
  45. size_t char_pos_;
  46. // The current character.
  47. int32_t char_;
  48. };
  49. class BASE_I18N_EXPORT UTF16CharIterator {
  50. public:
  51. // Requires |str| to live as long as the UTF16CharIterator does.
  52. explicit UTF16CharIterator(StringPiece16 str);
  53. UTF16CharIterator(UTF16CharIterator&& to_move);
  54. UTF16CharIterator& operator=(UTF16CharIterator&& to_move);
  55. UTF16CharIterator(const UTF16CharIterator&) = delete;
  56. UTF16CharIterator operator=(const UTF16CharIterator&) = delete;
  57. ~UTF16CharIterator();
  58. // Returns an iterator starting on the unicode character at offset
  59. // |array_index| into the string, or the previous array offset if
  60. // |array_index| is the second half of a surrogate pair.
  61. static UTF16CharIterator LowerBound(StringPiece16 str, size_t array_index);
  62. // Returns an iterator starting on the unicode character at offset
  63. // |array_index| into the string, or the next offset if |array_index| is the
  64. // second half of a surrogate pair.
  65. static UTF16CharIterator UpperBound(StringPiece16 str, size_t array_index);
  66. // Return the starting array index of the current character within the
  67. // string.
  68. size_t array_pos() const { return array_pos_; }
  69. // Returns the offset in code points from the initial iterator position, which
  70. // could be negative if Rewind() is called. The initial value is always zero,
  71. // regardless of how the iterator is constructed.
  72. int32_t char_offset() const { return char_offset_; }
  73. // Returns the code point at the current position.
  74. int32_t get() const { return char_; }
  75. // Returns the code point (i.e. the full Unicode character, not half of a
  76. // surrogate pair) following the current one. Should not be called if end() is
  77. // true. If the current code point is the last one in the string, returns
  78. // zero.
  79. int32_t NextCodePoint() const;
  80. // Returns the code point (i.e. the full Unicode character, not half of a
  81. // surrogate pair) preceding the current one. Should not be called if start()
  82. // is true.
  83. int32_t PreviousCodePoint() const;
  84. // Returns true if we're at the start of the string.
  85. bool start() const { return array_pos_ == 0; }
  86. // Returns true if we're at the end of the string.
  87. bool end() const { return array_pos_ == str_.length(); }
  88. // Advances to the next actual character. Returns false if we're at the
  89. // end of the string.
  90. bool Advance();
  91. // Moves to the previous actual character. Returns false if we're at the start
  92. // of the string.
  93. bool Rewind();
  94. private:
  95. UTF16CharIterator(base::StringPiece16 str, size_t initial_pos);
  96. // Fills in the current character we found and advances to the next
  97. // character, updating all flags as necessary.
  98. void ReadChar();
  99. // The string we're iterating over.
  100. StringPiece16 str_;
  101. // Array index.
  102. size_t array_pos_;
  103. // The next array index.
  104. size_t next_pos_;
  105. // Character offset from the initial position of the iterator.
  106. int32_t char_offset_;
  107. // The current character.
  108. int32_t char_;
  109. };
  110. } // namespace i18n
  111. } // namespace base
  112. #endif // BASE_I18N_CHAR_ITERATOR_H_