Commit 021cdfa1 authored by Xiaocheng Hu's avatar Xiaocheng Hu Committed by Commit Bot

Use unsigned integers in TextIterator

This patch changes TextIterator and its hellper classes to use unsigned
integers to get rid of unnecessary sign checks and type casts.

Public functions of TextIterator remain untouched.

Bug: 751353
Change-Id: I7b888d77fde272573c70f0a7fdbcc0410eec7e82
Reviewed-on: https://chromium-review.googlesource.com/595120
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491221}
parent f7bc18a9
......@@ -90,7 +90,7 @@ static bool NotSkipping(const Node& node) {
}
template <typename Strategy>
Node* StartNode(Node* start_container, int start_offset) {
Node* StartNode(Node* start_container, unsigned start_offset) {
if (start_container->IsCharacterDataNode())
return start_container;
if (Node* child = Strategy::ChildAt(*start_container, start_offset))
......@@ -101,18 +101,18 @@ Node* StartNode(Node* start_container, int start_offset) {
}
template <typename Strategy>
Node* EndNode(const Node& end_container, int end_offset) {
if (!end_container.IsCharacterDataNode() && end_offset > 0)
Node* EndNode(const Node& end_container, unsigned end_offset) {
if (!end_container.IsCharacterDataNode() && end_offset)
return Strategy::ChildAt(end_container, end_offset - 1);
return nullptr;
}
// This function is like Range::pastLastNode, except for the fact that it can
// This function is like Range::PastLastNode, except for the fact that it can
// climb up out of shadow trees and ignores all nodes that will be skipped in
// |advance()|.
template <typename Strategy>
Node* PastLastNode(const Node& range_end_container, int range_end_offset) {
if (range_end_offset >= 0 && !range_end_container.IsCharacterDataNode() &&
Node* PastLastNode(const Node& range_end_container, unsigned range_end_offset) {
if (!range_end_container.IsCharacterDataNode() &&
NotSkipping(range_end_container)) {
for (Node* next = Strategy::ChildAt(range_end_container, range_end_offset);
next; next = Strategy::NextSibling(*next)) {
......@@ -134,16 +134,16 @@ Node* PastLastNode(const Node& range_end_container, int range_end_offset) {
// Figure out the initial value of m_shadowDepth: the depth of startContainer's
// tree scope from the common ancestor tree scope.
template <typename Strategy>
int ShadowDepthOf(const Node& start_container, const Node& end_container);
unsigned ShadowDepthOf(const Node& start_container, const Node& end_container);
template <>
int ShadowDepthOf<EditingStrategy>(const Node& start_container,
const Node& end_container) {
unsigned ShadowDepthOf<EditingStrategy>(const Node& start_container,
const Node& end_container) {
const TreeScope* common_ancestor_tree_scope =
start_container.GetTreeScope().CommonAncestorTreeScope(
end_container.GetTreeScope());
DCHECK(common_ancestor_tree_scope);
int shadow_depth = 0;
unsigned shadow_depth = 0;
for (const TreeScope* tree_scope = &start_container.GetTreeScope();
tree_scope != common_ancestor_tree_scope;
tree_scope = tree_scope->ParentTreeScope())
......@@ -152,8 +152,8 @@ int ShadowDepthOf<EditingStrategy>(const Node& start_container,
}
template <>
int ShadowDepthOf<EditingInFlatTreeStrategy>(const Node& start_container,
const Node& end_container) {
unsigned ShadowDepthOf<EditingInFlatTreeStrategy>(const Node& start_container,
const Node& end_container) {
return 0;
}
......@@ -277,7 +277,7 @@ void TextIteratorAlgorithm<Strategy>::Advance() {
if (HandleRememberedProgress())
return;
while (node_ && (node_ != past_end_node_ || shadow_depth_ > 0)) {
while (node_ && (node_ != past_end_node_ || shadow_depth_)) {
if (!should_stop_ && StopsOnFormControls() &&
HTMLFormControlElement::EnclosingFormControlElement(node_))
should_stop_ = true;
......@@ -399,7 +399,7 @@ void TextIteratorAlgorithm<Strategy>::Advance() {
next = Strategy::NextSibling(*node_);
}
if (!next && !parent_node && shadow_depth_ > 0) {
if (!next && !parent_node && shadow_depth_) {
// 4. Reached the top of a shadow root. If it's created by author,
// then try to visit the next
// sibling shadow root, if any.
......@@ -829,8 +829,8 @@ template <typename Strategy>
void TextIteratorAlgorithm<Strategy>::SpliceBuffer(UChar c,
Node* text_node,
Node* offset_base_node,
int text_start_offset,
int text_end_offset) {
unsigned text_start_offset,
unsigned text_end_offset) {
text_state_.SpliceBuffer(c, text_node, offset_base_node, text_start_offset,
text_end_offset);
text_node_handler_.ResetCollapsedWhiteSpaceFixup();
......@@ -947,9 +947,8 @@ bool TextIteratorAlgorithm<Strategy>::IsInTextSecurityMode() const {
template <typename Strategy>
bool TextIteratorAlgorithm<Strategy>::IsBetweenSurrogatePair(
int position) const {
DCHECK_GE(position, 0);
return position > 0 && position < length() &&
unsigned position) const {
return position > 0 && position < static_cast<unsigned>(length()) &&
U16_IS_LEAD(CharacterAt(position - 1)) &&
U16_IS_TRAIL(CharacterAt(position));
}
......@@ -958,10 +957,10 @@ template <typename Strategy>
int TextIteratorAlgorithm<Strategy>::CopyTextTo(ForwardsTextBuffer* output,
int position,
int min_length) const {
int end = std::min(length(), position + min_length);
unsigned end = std::min(length(), position + min_length);
if (IsBetweenSurrogatePair(end))
++end;
int copied_length = end - position;
unsigned copied_length = end - position;
CopyCodeUnitsTo(output, position, copied_length);
return copied_length;
}
......@@ -975,8 +974,8 @@ int TextIteratorAlgorithm<Strategy>::CopyTextTo(ForwardsTextBuffer* output,
template <typename Strategy>
void TextIteratorAlgorithm<Strategy>::CopyCodeUnitsTo(
ForwardsTextBuffer* output,
int position,
int copy_length) const {
unsigned position,
unsigned copy_length) const {
text_state_.AppendTextTo(output, position, copy_length);
}
......
......@@ -147,8 +147,8 @@ class CORE_TEMPLATE_CLASS_EXPORT TextIteratorAlgorithm {
void SpliceBuffer(UChar,
Node* text_node,
Node* offset_base_node,
int text_start_offset,
int text_end_offset);
unsigned text_start_offset,
unsigned text_end_offset);
// Used by selection preservation code. There should be one character emitted
// between every VisiblePosition in the Range used to create the TextIterator.
......@@ -192,19 +192,19 @@ class CORE_TEMPLATE_CLASS_EXPORT TextIteratorAlgorithm {
bool ForInnerText() const { return behavior_.ForInnerText(); }
bool IsBetweenSurrogatePair(int position) const;
bool IsBetweenSurrogatePair(unsigned position) const;
// Append code units with offset range [position, position + copyLength)
// to the output buffer.
void CopyCodeUnitsTo(ForwardsTextBuffer* output,
int position,
int copy_length) const;
unsigned position,
unsigned copy_length) const;
// The range.
const Member<Node> start_container_;
const int start_offset_;
const unsigned start_offset_;
const Member<Node> end_container_;
const int end_offset_;
const unsigned end_offset_;
// |m_endNode| stores |Strategy::childAt(*m_endContainer, m_endOffset - 1)|,
// if it exists, or |nullptr| otherwise.
const Member<Node> end_node_;
......@@ -215,7 +215,7 @@ class CORE_TEMPLATE_CLASS_EXPORT TextIteratorAlgorithm {
Member<Node> node_;
IterationProgress iteration_progress_;
FullyClippedStateStackAlgorithm<Strategy> fully_clipped_stack_;
int shadow_depth_;
unsigned shadow_depth_;
// Used when there is still some pending text from the current node; when
// these are false, we go back to normal iterating.
......
......@@ -40,7 +40,7 @@ bool TextIteratorTextNodeHandler::ShouldHandleFirstLetter(
if (!layout_text.IsTextFragment())
return false;
const LayoutTextFragment& text_fragment = ToLayoutTextFragment(layout_text);
return offset_ < static_cast<int>(text_fragment.TextStartOffset());
return offset_ < text_fragment.TextStartOffset();
}
static bool HasVisibleTextNode(LayoutText* layout_object) {
......@@ -83,8 +83,7 @@ void TextIteratorTextNodeHandler::HandlePreFormattedTextNode() {
if (first_letter_text_) {
const String first_letter = first_letter_text_->GetText();
const unsigned run_start = offset_;
const bool stops_in_first_letter =
end_offset_ <= static_cast<int>(first_letter.length());
const bool stops_in_first_letter = end_offset_ <= first_letter.length();
const unsigned run_end =
stops_in_first_letter ? end_offset_ : first_letter.length();
EmitText(text_node_, first_letter_text_, run_start, run_end);
......@@ -103,7 +102,7 @@ void TextIteratorTextNodeHandler::HandlePreFormattedTextNode() {
if (layout_object->Style()->Visibility() != EVisibility::kVisible &&
!IgnoresStyleVisibility())
return;
DCHECK_GE(static_cast<unsigned>(offset_), layout_object->TextStartOffset());
DCHECK_GE(offset_, layout_object->TextStartOffset());
const unsigned run_start = offset_ - layout_object->TextStartOffset();
const unsigned str_length = str.length();
const unsigned end = end_offset_ - layout_object->TextStartOffset();
......@@ -116,17 +115,16 @@ void TextIteratorTextNodeHandler::HandlePreFormattedTextNode() {
}
void TextIteratorTextNodeHandler::HandleTextNodeInRange(Text* node,
int start_offset,
int end_offset) {
unsigned start_offset,
unsigned end_offset) {
DCHECK(node);
DCHECK_GE(start_offset, 0);
// TODO(editing-dev): Add the following DCHECK once we stop assuming equal
// number of code units in DOM string and LayoutText::GetText(). Currently
// violated by
// - external/wpt/innerText/getter.html
// - fast/css/case-transform.html
// DCHECK_LE(end_offset, static_cast<int>(node->data().length()));
// DCHECK_LE(end_offset, node->data().length());
// TODO(editing-dev): Stop passing in |start_offset == end_offset|.
DCHECK_LE(start_offset, end_offset);
......@@ -182,15 +180,16 @@ void TextIteratorTextNodeHandler::HandleTextNodeInRange(Text* node,
HandleTextBox();
}
void TextIteratorTextNodeHandler::HandleTextNodeStartFrom(Text* node,
int start_offset) {
void TextIteratorTextNodeHandler::HandleTextNodeStartFrom(
Text* node,
unsigned start_offset) {
HandleTextNodeInRange(node, start_offset,
node->GetLayoutObject()->TextStartOffset() +
node->GetLayoutObject()->GetText().length());
}
void TextIteratorTextNodeHandler::HandleTextNodeEndAt(Text* node,
int end_offset) {
unsigned end_offset) {
HandleTextNodeInRange(node, 0, end_offset);
}
......@@ -240,7 +239,7 @@ void TextIteratorTextNodeHandler::HandleTextBox() {
// Start and end offsets in |str|, i.e., str[start..end - 1] should be
// emitted (after handling whitespace collapsing).
const unsigned start = offset_ - layout_object->TextStartOffset();
const unsigned end = static_cast<unsigned>(end_offset_) - text_start_offset;
const unsigned end = end_offset_ - text_start_offset;
while (text_box_) {
const unsigned text_box_start = text_box_->Start();
const unsigned run_start = std::max(text_box_start, start);
......@@ -323,8 +322,7 @@ void TextIteratorTextNodeHandler::HandleTextBox() {
// If we are doing a subrun that doesn't go to the end of the text box,
// come back again to finish handling this text box; don't advance to
// the next one.
if (static_cast<unsigned>(text_state_.PositionEndOffset()) <
text_box_end + text_start_offset)
if (text_state_.PositionEndOffset() < text_box_end + text_start_offset)
return;
if (behavior_.DoesNotEmitSpaceBeyondRangeEnd()) {
......@@ -433,8 +431,8 @@ void TextIteratorTextNodeHandler::ResetCollapsedWhiteSpaceFixup() {
void TextIteratorTextNodeHandler::SpliceBuffer(UChar c,
Node* text_node,
Node* offset_base_node,
int text_start_offset,
int text_end_offset) {
unsigned text_start_offset,
unsigned text_end_offset) {
text_state_.SpliceBuffer(c, text_node, offset_base_node, text_start_offset,
text_end_offset);
ResetCollapsedWhiteSpaceFixup();
......@@ -442,8 +440,8 @@ void TextIteratorTextNodeHandler::SpliceBuffer(UChar c,
void TextIteratorTextNodeHandler::EmitText(Node* text_node,
LayoutText* layout_object,
int text_start_offset,
int text_end_offset) {
unsigned text_start_offset,
unsigned text_end_offset) {
String string = behavior_.EmitsOriginalText() ? layout_object->OriginalText()
: layout_object->GetText();
if (behavior_.EmitsSpaceForNbsp())
......
......@@ -40,9 +40,9 @@ class TextIteratorTextNodeHandler {
void HandleTextNodeWhole(Text*);
// Variants that emit plain text within the given DOM offset range.
void HandleTextNodeStartFrom(Text*, int start_offset);
void HandleTextNodeEndAt(Text*, int end_offset);
void HandleTextNodeInRange(Text*, int start_offset, int end_offset);
void HandleTextNodeStartFrom(Text*, unsigned start_offset);
void HandleTextNodeEndAt(Text*, unsigned end_offset);
void HandleTextNodeInRange(Text*, unsigned start_offset, unsigned end_offset);
private:
void HandlePreFormattedTextNode();
......@@ -62,17 +62,17 @@ class TextIteratorTextNodeHandler {
void SpliceBuffer(UChar,
Node* text_node,
Node* offset_base_node,
int text_start_offset,
int text_end_offset);
unsigned text_start_offset,
unsigned text_end_offset);
void EmitText(Node* text_node,
LayoutText* layout_object,
int text_start_offset,
int text_end_offset);
unsigned text_start_offset,
unsigned text_end_offset);
// The current text node and offset range, from which text should be emitted.
Member<Text> text_node_;
int offset_ = 0;
int end_offset_ = 0;
unsigned offset_ = 0;
unsigned end_offset_ = 0;
InlineTextBox* text_box_ = nullptr;
......
......@@ -33,13 +33,13 @@
namespace blink {
UChar TextIteratorTextState::CharacterAt(unsigned index) const {
SECURITY_DCHECK(index < static_cast<unsigned>(length()));
if (!(index < static_cast<unsigned>(length())))
SECURITY_DCHECK(index < length());
if (!(index < length()))
return 0;
if (single_character_buffer_) {
DCHECK_EQ(index, 0u);
DCHECK_EQ(length(), 1);
DCHECK_EQ(length(), 1u);
return single_character_buffer_;
}
......@@ -48,8 +48,8 @@ UChar TextIteratorTextState::CharacterAt(unsigned index) const {
String TextIteratorTextState::Substring(unsigned position,
unsigned length) const {
SECURITY_DCHECK(position <= static_cast<unsigned>(this->length()));
SECURITY_DCHECK(position + length <= static_cast<unsigned>(this->length()));
SECURITY_DCHECK(position <= this->length());
SECURITY_DCHECK(position + length <= this->length());
if (!length)
return g_empty_string;
if (single_character_buffer_) {
......@@ -64,8 +64,8 @@ void TextIteratorTextState::AppendTextToStringBuilder(
StringBuilder& builder,
unsigned position,
unsigned max_length) const {
unsigned length_to_append =
std::min(static_cast<unsigned>(length()) - position, max_length);
SECURITY_DCHECK(position <= this->length());
unsigned length_to_append = std::min(length() - position, max_length);
if (!length_to_append)
return;
if (single_character_buffer_) {
......@@ -99,7 +99,7 @@ void TextIteratorTextState::EmitAltText(Node* node) {
void TextIteratorTextState::FlushPositionOffsets() const {
if (!position_offset_base_node_)
return;
int index = position_offset_base_node_->NodeIndex();
unsigned index = position_offset_base_node_->NodeIndex();
position_start_offset_ += index;
position_end_offset_ += index;
position_offset_base_node_ = nullptr;
......@@ -108,8 +108,8 @@ void TextIteratorTextState::FlushPositionOffsets() const {
void TextIteratorTextState::SpliceBuffer(UChar c,
Node* text_node,
Node* offset_base_node,
int text_start_offset,
int text_end_offset) {
unsigned text_start_offset,
unsigned text_end_offset) {
DCHECK(text_node);
has_emitted_ = true;
......@@ -133,19 +133,17 @@ void TextIteratorTextState::SpliceBuffer(UChar c,
}
void TextIteratorTextState::EmitText(Node* text_node,
int position_start_offset,
int position_end_offset,
unsigned position_start_offset,
unsigned position_end_offset,
const String& string,
int text_start_offset,
int text_end_offset) {
unsigned text_start_offset,
unsigned text_end_offset) {
DCHECK(text_node);
text_ = string;
DCHECK(!text_.IsEmpty());
DCHECK_LE(0, text_start_offset);
DCHECK_LT(text_start_offset, static_cast<int>(text_.length()));
DCHECK_LE(0, text_end_offset);
DCHECK_LE(text_end_offset, static_cast<int>(text_.length()));
DCHECK_LT(text_start_offset, text_.length());
DCHECK_LE(text_end_offset, text_.length());
DCHECK_LE(text_start_offset, text_end_offset);
position_node_ = text_node;
......@@ -163,8 +161,7 @@ void TextIteratorTextState::EmitText(Node* text_node,
void TextIteratorTextState::AppendTextTo(ForwardsTextBuffer* output,
unsigned position,
unsigned length_to_append) const {
SECURITY_DCHECK(position + length_to_append <=
static_cast<unsigned>(length()));
SECURITY_DCHECK(position + length_to_append <= length());
// Make sure there's no integer overflow.
SECURITY_DCHECK(position + length_to_append >= position);
if (!length_to_append)
......@@ -172,7 +169,7 @@ void TextIteratorTextState::AppendTextTo(ForwardsTextBuffer* output,
DCHECK(output);
if (single_character_buffer_) {
DCHECK_EQ(position, 0u);
DCHECK_EQ(length(), 1);
DCHECK_EQ(length(), 1u);
output->PushCharacters(single_character_buffer_, 1);
return;
}
......
......@@ -40,7 +40,7 @@ class CORE_EXPORT TextIteratorTextState {
TextIteratorTextState() = default;
// Return properties of the current text.
int length() const { return text_length_; }
unsigned length() const { return text_length_; }
UChar CharacterAt(unsigned index) const;
String Substring(unsigned position, unsigned length) const;
void AppendTextToStringBuilder(StringBuilder&,
......@@ -53,21 +53,21 @@ class CORE_EXPORT TextIteratorTextState {
void SpliceBuffer(UChar,
Node* text_node,
Node* offset_base_node,
int text_start_offset,
int text_end_offset);
unsigned text_start_offset,
unsigned text_end_offset);
void EmitText(Node*,
int position_start_offset,
int position_end_offset,
unsigned position_start_offset,
unsigned position_end_offset,
const String&,
int text_start_offset,
int text_end_offset);
unsigned text_start_offset,
unsigned text_end_offset);
void EmitAltText(Node*);
void UpdateForReplacedElement(Node* base_node);
// Return position of the current text.
void FlushPositionOffsets() const;
int PositionStartOffset() const { return position_start_offset_; }
int PositionEndOffset() const { return position_end_offset_; }
unsigned PositionStartOffset() const { return position_start_offset_; }
unsigned PositionEndOffset() const { return position_end_offset_; }
Node* PositionNode() const { return position_node_; }
bool HasEmitted() const { return has_emitted_; }
......@@ -78,7 +78,7 @@ class CORE_EXPORT TextIteratorTextState {
}
private:
int text_length_ = 0;
unsigned text_length_ = 0;
// Used for whitespace characters that aren't in the DOM, so we can point at
// them.
......@@ -88,13 +88,13 @@ class CORE_EXPORT TextIteratorTextState {
// The current text when |single_character_buffer_| is zero, in which case it
// is |text_.Substring(text_start_offset_, text_length_)|.
String text_;
int text_start_offset_ = 0;
unsigned text_start_offset_ = 0;
// Position of the current text, in the form to be returned from the iterator.
Member<Node> position_node_;
mutable Member<Node> position_offset_base_node_;
mutable int position_start_offset_ = 0;
mutable int position_end_offset_ = 0;
mutable unsigned position_start_offset_ = 0;
mutable unsigned position_end_offset_ = 0;
// Used when deciding whether to emit a "positioning" (e.g. newline) before
// any other content
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment