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