1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/i18n/char_iterator.h"
6
7 #include <string_view>
8
9 #include "base/check_op.h"
10 #include "base/third_party/icu/icu_utf.h"
11
12 namespace base {
13 namespace i18n {
14
15 // UTF8CharIterator ------------------------------------------------------------
16
UTF8CharIterator(std::string_view str)17 UTF8CharIterator::UTF8CharIterator(std::string_view str)
18 : str_(str), array_pos_(0), next_pos_(0), char_pos_(0), char_(0) {
19 if (!str_.empty())
20 CBU8_NEXT(str_.data(), next_pos_, str_.length(), char_);
21 }
22
23 UTF8CharIterator::~UTF8CharIterator() = default;
24
Advance()25 bool UTF8CharIterator::Advance() {
26 if (array_pos_ >= str_.length())
27 return false;
28
29 array_pos_ = next_pos_;
30 char_pos_++;
31 if (next_pos_ < str_.length())
32 CBU8_NEXT(str_.data(), next_pos_, str_.length(), char_);
33
34 return true;
35 }
36
37 // UTF16CharIterator -----------------------------------------------------------
38
UTF16CharIterator(std::u16string_view str)39 UTF16CharIterator::UTF16CharIterator(std::u16string_view str)
40 : UTF16CharIterator(str, 0) {}
41
42 UTF16CharIterator::UTF16CharIterator(UTF16CharIterator&& to_move) = default;
43
44 UTF16CharIterator::~UTF16CharIterator() = default;
45
46 UTF16CharIterator& UTF16CharIterator::operator=(UTF16CharIterator&& to_move) =
47 default;
48
49 // static
LowerBound(std::u16string_view str,size_t array_index)50 UTF16CharIterator UTF16CharIterator::LowerBound(std::u16string_view str,
51 size_t array_index) {
52 DCHECK_LE(array_index, str.length());
53 CBU16_SET_CP_START(str.data(), 0, array_index);
54 return UTF16CharIterator(str, array_index);
55 }
56
57 // static
UpperBound(std::u16string_view str,size_t array_index)58 UTF16CharIterator UTF16CharIterator::UpperBound(std::u16string_view str,
59 size_t array_index) {
60 DCHECK_LE(array_index, str.length());
61 CBU16_SET_CP_LIMIT(str.data(), 0, array_index, str.length());
62 return UTF16CharIterator(str, array_index);
63 }
64
NextCodePoint() const65 int32_t UTF16CharIterator::NextCodePoint() const {
66 if (next_pos_ >= str_.length())
67 return 0;
68
69 base_icu::UChar32 c;
70 CBU16_GET(str_.data(), 0, next_pos_, str_.length(), c);
71 return c;
72 }
73
PreviousCodePoint() const74 int32_t UTF16CharIterator::PreviousCodePoint() const {
75 if (array_pos_ == 0)
76 return 0;
77
78 uint32_t pos = array_pos_;
79 base_icu::UChar32 c;
80 CBU16_PREV(str_.data(), 0, pos, c);
81 return c;
82 }
83
Advance()84 bool UTF16CharIterator::Advance() {
85 if (array_pos_ >= str_.length())
86 return false;
87
88 array_pos_ = next_pos_;
89 char_offset_++;
90 if (next_pos_ < str_.length())
91 ReadChar();
92
93 return true;
94 }
95
Rewind()96 bool UTF16CharIterator::Rewind() {
97 if (array_pos_ == 0)
98 return false;
99
100 next_pos_ = array_pos_;
101 char_offset_--;
102 CBU16_PREV(str_.data(), 0, array_pos_, char_);
103 return true;
104 }
105
UTF16CharIterator(std::u16string_view str,size_t initial_pos)106 UTF16CharIterator::UTF16CharIterator(std::u16string_view str,
107 size_t initial_pos)
108 : str_(str),
109 array_pos_(initial_pos),
110 next_pos_(initial_pos),
111 char_offset_(0),
112 char_(0) {
113 // This has the side-effect of advancing |next_pos_|.
114 if (array_pos_ < str_.length())
115 ReadChar();
116 }
117
ReadChar()118 void UTF16CharIterator::ReadChar() {
119 // This is actually a huge macro, so is worth having in a separate function.
120 CBU16_NEXT(str_.data(), next_pos_, str_.length(), char_);
121 }
122
123 } // namespace i18n
124 } // namespace base
125