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