• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7 #pragma allow_unsafe_buffers
8 #endif
9 
10 #include "base/i18n/char_iterator.h"
11 
12 #include <string_view>
13 
14 #include "base/check_op.h"
15 #include "base/third_party/icu/icu_utf.h"
16 
17 namespace base {
18 namespace i18n {
19 
20 // UTF8CharIterator ------------------------------------------------------------
21 
UTF8CharIterator(std::string_view str)22 UTF8CharIterator::UTF8CharIterator(std::string_view str)
23     : str_(str), array_pos_(0), next_pos_(0), char_pos_(0), char_(0) {
24   if (!str_.empty())
25     CBU8_NEXT(str_.data(), next_pos_, str_.length(), char_);
26 }
27 
28 UTF8CharIterator::~UTF8CharIterator() = default;
29 
Advance()30 bool UTF8CharIterator::Advance() {
31   if (array_pos_ >= str_.length())
32     return false;
33 
34   array_pos_ = next_pos_;
35   char_pos_++;
36   if (next_pos_ < str_.length())
37     CBU8_NEXT(str_.data(), next_pos_, str_.length(), char_);
38 
39   return true;
40 }
41 
42 // UTF16CharIterator -----------------------------------------------------------
43 
UTF16CharIterator(std::u16string_view str)44 UTF16CharIterator::UTF16CharIterator(std::u16string_view str)
45     : UTF16CharIterator(str, 0) {}
46 
47 UTF16CharIterator::UTF16CharIterator(UTF16CharIterator&& to_move) = default;
48 
49 UTF16CharIterator::~UTF16CharIterator() = default;
50 
51 UTF16CharIterator& UTF16CharIterator::operator=(UTF16CharIterator&& to_move) =
52     default;
53 
54 // static
LowerBound(std::u16string_view str,size_t array_index)55 UTF16CharIterator UTF16CharIterator::LowerBound(std::u16string_view str,
56                                                 size_t array_index) {
57   DCHECK_LE(array_index, str.length());
58   CBU16_SET_CP_START(str.data(), 0, array_index);
59   return UTF16CharIterator(str, array_index);
60 }
61 
62 // static
UpperBound(std::u16string_view str,size_t array_index)63 UTF16CharIterator UTF16CharIterator::UpperBound(std::u16string_view str,
64                                                 size_t array_index) {
65   DCHECK_LE(array_index, str.length());
66   CBU16_SET_CP_LIMIT(str.data(), 0, array_index, str.length());
67   return UTF16CharIterator(str, array_index);
68 }
69 
NextCodePoint() const70 int32_t UTF16CharIterator::NextCodePoint() const {
71   if (next_pos_ >= str_.length())
72     return 0;
73 
74   base_icu::UChar32 c;
75   CBU16_GET(str_.data(), 0, next_pos_, str_.length(), c);
76   return c;
77 }
78 
PreviousCodePoint() const79 int32_t UTF16CharIterator::PreviousCodePoint() const {
80   if (array_pos_ == 0)
81     return 0;
82 
83   uint32_t pos = array_pos_;
84   base_icu::UChar32 c;
85   CBU16_PREV(str_.data(), 0, pos, c);
86   return c;
87 }
88 
Advance()89 bool UTF16CharIterator::Advance() {
90   if (array_pos_ >= str_.length())
91     return false;
92 
93   array_pos_ = next_pos_;
94   char_offset_++;
95   if (next_pos_ < str_.length())
96     ReadChar();
97 
98   return true;
99 }
100 
Rewind()101 bool UTF16CharIterator::Rewind() {
102   if (array_pos_ == 0)
103     return false;
104 
105   next_pos_ = array_pos_;
106   char_offset_--;
107   CBU16_PREV(str_.data(), 0, array_pos_, char_);
108   return true;
109 }
110 
UTF16CharIterator(std::u16string_view str,size_t initial_pos)111 UTF16CharIterator::UTF16CharIterator(std::u16string_view str,
112                                      size_t initial_pos)
113     : str_(str),
114       array_pos_(initial_pos),
115       next_pos_(initial_pos),
116       char_offset_(0),
117       char_(0) {
118   // This has the side-effect of advancing |next_pos_|.
119   if (array_pos_ < str_.length())
120     ReadChar();
121 }
122 
ReadChar()123 void UTF16CharIterator::ReadChar() {
124   // This is actually a huge macro, so is worth having in a separate function.
125   CBU16_NEXT(str_.data(), next_pos_, str_.length(), char_);
126 }
127 
128 }  // namespace i18n
129 }  // namespace base
130