xref: /aosp_15_r20/external/cronet/base/i18n/char_iterator.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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