Index: third_party/WebKit/Source/core/editing/iterators/TextAccumulator.h |
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextAccumulator.h b/third_party/WebKit/Source/core/editing/iterators/TextAccumulator.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e555b6bb6e023396ec87e8e9d5da14e510beb5bb |
--- /dev/null |
+++ b/third_party/WebKit/Source/core/editing/iterators/TextAccumulator.h |
@@ -0,0 +1,76 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef TextAccumulator_h |
+#define TextAccumulator_h |
+ |
+#include "core/editing/iterators/TextBuffer.h" |
+ |
+namespace blink { |
+ |
+template<typename Buffer> |
+class TextAccumulator { |
+ STACK_ALLOCATED(); |
+public: |
+ |
+ TextAccumulator() |
+#ifndef NDEBUG |
+ : m_maxAccumulate(2) |
+#else |
+ : m_maxAccumulate(1024) |
+#endif // NDEBUG |
+ , m_accumulatedInCurrentNode(0) |
+ { |
+ } |
+ |
+ const UChar* data() const { return m_buffer.data(); } |
+ unsigned size() const { return m_buffer.size(); } |
+ int accumulatedLengthInCurrentNode() const { return m_accumulatedInCurrentNode; } |
+ |
+ void push(const UChar* other, unsigned length) { m_buffer.push(other, length); } |
+ |
+ template<typename Iterator> |
+ void extract(const Iterator& it) |
+ { |
+ ASSERT(m_maxAccumulate > 0); |
+ ASSERT(m_accumulatedInCurrentNode >= 0); |
+ ASSERT(m_accumulatedInCurrentNode <= it.length()); |
+ int accumulateLength = std::min(it.length() - m_accumulatedInCurrentNode, m_maxAccumulate); |
+ if (it.isInTextSecurityMode()) { |
+ // Treat bullets used in the text security mode as regular |
+ // characters when looking for boundaries |
+ m_buffer.push('x', accumulateLength); |
+ } else { |
+ accumulateLength = it.copyTextTo(m_buffer, m_accumulatedInCurrentNode, accumulateLength); |
+ } |
+ m_accumulatedInCurrentNode += accumulateLength; |
+ if (accumulateLength >= m_maxAccumulate) |
+ m_maxAccumulate *= 2; |
+ } |
+ |
+ template<typename Iterator> |
+ void advance(Iterator& it) |
+ { |
+ ASSERT(m_accumulatedInCurrentNode >= 0); |
+ ASSERT(m_accumulatedInCurrentNode <= it.length()); |
+ ASSERT(!it.atEnd()); |
+ if (m_accumulatedInCurrentNode == it.length()) { |
+ m_accumulatedInCurrentNode = 0; |
+ it.advance(); |
+ } |
+ } |
+ |
+private: |
+ |
+ Buffer m_buffer; |
+ int m_maxAccumulate; |
+ int m_accumulatedInCurrentNode; |
+}; |
+ |
+using ForwardsTextAccumulator = TextAccumulator<ForwardsTextBuffer>; |
+using BackwardsTextAccumulator = TextAccumulator<BackwardsTextBuffer>; |
+ |
+} // namespace blink |
+ |
+#endif // TextAccumulator_h |