Index: Source/WTF/wtf/text/StringBuilder.cpp |
diff --git a/Source/WTF/wtf/text/StringBuilder.cpp b/Source/WTF/wtf/text/StringBuilder.cpp |
deleted file mode 100644 |
index 82262d2a8f0348485bc5dabffb60454bf05169b1..0000000000000000000000000000000000000000 |
--- a/Source/WTF/wtf/text/StringBuilder.cpp |
+++ /dev/null |
@@ -1,343 +0,0 @@ |
-/* |
- * Copyright (C) 2010 Apple Inc. All rights reserved. |
- * Copyright (C) 2012 Google Inc. All rights reserved. |
- * |
- * Redistribution and use in source and binary forms, with or without |
- * modification, are permitted provided that the following conditions |
- * are met: |
- * 1. Redistributions of source code must retain the above copyright |
- * notice, this list of conditions and the following disclaimer. |
- * 2. Redistributions in binary form must reproduce the above copyright |
- * notice, this list of conditions and the following disclaimer in the |
- * documentation and/or other materials provided with the distribution. |
- * |
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
- */ |
- |
-#include "config.h" |
-#include "StringBuilder.h" |
- |
-#include "IntegerToStringConversion.h" |
-#include "WTFString.h" |
- |
-namespace WTF { |
- |
-static const unsigned minimumCapacity = 16; |
- |
-void StringBuilder::reifyString() const |
-{ |
- // Check if the string already exists. |
- if (!m_string.isNull()) { |
- ASSERT(m_string.length() == m_length); |
- return; |
- } |
- |
- // Check for empty. |
- if (!m_length) { |
- m_string = StringImpl::empty(); |
- return; |
- } |
- |
- // Must be valid in the buffer, take a substring (unless string fills the buffer). |
- ASSERT(m_buffer && m_length <= m_buffer->length()); |
- m_string = (m_length == m_buffer->length()) |
- ? m_buffer.get() |
- : StringImpl::create(m_buffer, 0, m_length); |
- |
- if (m_buffer->has16BitShadow() && m_valid16BitShadowLength < m_length) |
- m_buffer->upconvertCharacters(m_valid16BitShadowLength, m_length); |
- |
- m_valid16BitShadowLength = m_length; |
-} |
- |
-void StringBuilder::resize(unsigned newSize) |
-{ |
- // Check newSize < m_length, hence m_length > 0. |
- ASSERT(newSize <= m_length); |
- if (newSize == m_length) |
- return; |
- ASSERT(m_length); |
- |
- // If there is a buffer, we only need to duplicate it if it has more than one ref. |
- if (m_buffer) { |
- m_string = String(); // Clear the string to remove the reference to m_buffer if any before checking the reference count of m_buffer. |
- if (!m_buffer->hasOneRef()) { |
- if (m_buffer->is8Bit()) |
- allocateBuffer(m_buffer->characters8(), m_buffer->length()); |
- else |
- allocateBuffer(m_buffer->characters16(), m_buffer->length()); |
- } |
- m_length = newSize; |
- return; |
- } |
- |
- // Since m_length && !m_buffer, the string must be valid in m_string, and m_string.length() > 0. |
- ASSERT(!m_string.isEmpty()); |
- ASSERT(m_length == m_string.length()); |
- ASSERT(newSize < m_string.length()); |
- m_length = newSize; |
- m_string = StringImpl::create(m_string.impl(), 0, newSize); |
-} |
- |
-// Allocate a new 8 bit buffer, copying in currentCharacters (these may come from either m_string |
-// or m_buffer, neither will be reassigned until the copy has completed). |
-void StringBuilder::allocateBuffer(const LChar* currentCharacters, unsigned requiredLength) |
-{ |
- ASSERT(m_is8Bit); |
- // Copy the existing data into a new buffer, set result to point to the end of the existing data. |
- RefPtr<StringImpl> buffer = StringImpl::createUninitialized(requiredLength, m_bufferCharacters8); |
- memcpy(m_bufferCharacters8, currentCharacters, static_cast<size_t>(m_length) * sizeof(LChar)); // This can't overflow. |
- |
- // Update the builder state. |
- m_buffer = buffer.release(); |
- m_string = String(); |
-} |
- |
-// Allocate a new 16 bit buffer, copying in currentCharacters (these may come from either m_string |
-// or m_buffer, neither will be reassigned until the copy has completed). |
-void StringBuilder::allocateBuffer(const UChar* currentCharacters, unsigned requiredLength) |
-{ |
- ASSERT(!m_is8Bit); |
- // Copy the existing data into a new buffer, set result to point to the end of the existing data. |
- RefPtr<StringImpl> buffer = StringImpl::createUninitialized(requiredLength, m_bufferCharacters16); |
- memcpy(m_bufferCharacters16, currentCharacters, static_cast<size_t>(m_length) * sizeof(UChar)); // This can't overflow. |
- |
- // Update the builder state. |
- m_buffer = buffer.release(); |
- m_string = String(); |
-} |
- |
-// Allocate a new 16 bit buffer, copying in currentCharacters (which is 8 bit and may come |
-// from either m_string or m_buffer, neither will be reassigned until the copy has completed). |
-void StringBuilder::allocateBufferUpConvert(const LChar* currentCharacters, unsigned requiredLength) |
-{ |
- ASSERT(m_is8Bit); |
- // Copy the existing data into a new buffer, set result to point to the end of the existing data. |
- RefPtr<StringImpl> buffer = StringImpl::createUninitialized(requiredLength, m_bufferCharacters16); |
- for (unsigned i = 0; i < m_length; ++i) |
- m_bufferCharacters16[i] = currentCharacters[i]; |
- |
- m_is8Bit = false; |
- |
- // Update the builder state. |
- m_buffer = buffer.release(); |
- m_string = String(); |
-} |
- |
-template <> |
-void StringBuilder::reallocateBuffer<LChar>(unsigned requiredLength) |
-{ |
- // If the buffer has only one ref (by this StringBuilder), reallocate it, |
- // otherwise fall back to "allocate and copy" method. |
- m_string = String(); |
- |
- ASSERT(m_is8Bit); |
- ASSERT(m_buffer->is8Bit()); |
- |
- if (m_buffer->hasOneRef()) |
- m_buffer = StringImpl::reallocate(m_buffer.release(), requiredLength, m_bufferCharacters8); |
- else |
- allocateBuffer(m_buffer->characters8(), requiredLength); |
-} |
- |
-template <> |
-void StringBuilder::reallocateBuffer<UChar>(unsigned requiredLength) |
-{ |
- // If the buffer has only one ref (by this StringBuilder), reallocate it, |
- // otherwise fall back to "allocate and copy" method. |
- m_string = String(); |
- |
- if (m_buffer->is8Bit()) |
- allocateBufferUpConvert(m_buffer->characters8(), requiredLength); |
- else if (m_buffer->hasOneRef()) |
- m_buffer = StringImpl::reallocate(m_buffer.release(), requiredLength, m_bufferCharacters16); |
- else |
- allocateBuffer(m_buffer->characters16(), requiredLength); |
-} |
- |
-void StringBuilder::reserveCapacity(unsigned newCapacity) |
-{ |
- if (m_buffer) { |
- // If there is already a buffer, then grow if necessary. |
- if (newCapacity > m_buffer->length()) { |
- if (m_buffer->is8Bit()) |
- reallocateBuffer<LChar>(newCapacity); |
- else |
- reallocateBuffer<UChar>(newCapacity); |
- } |
- } else { |
- // Grow the string, if necessary. |
- if (newCapacity > m_length) { |
- if (!m_length) { |
- LChar* nullPlaceholder = 0; |
- allocateBuffer(nullPlaceholder, newCapacity); |
- } else if (m_string.is8Bit()) |
- allocateBuffer(m_string.characters8(), newCapacity); |
- else |
- allocateBuffer(m_string.characters16(), newCapacity); |
- } |
- } |
-} |
- |
-// Make 'length' additional capacity be available in m_buffer, update m_string & m_length, |
-// return a pointer to the newly allocated storage. |
-template <typename CharType> |
-ALWAYS_INLINE CharType* StringBuilder::appendUninitialized(unsigned length) |
-{ |
- ASSERT(length); |
- |
- // Calculate the new size of the builder after appending. |
- unsigned requiredLength = length + m_length; |
- RELEASE_ASSERT(requiredLength >= length); |
- |
- if ((m_buffer) && (requiredLength <= m_buffer->length())) { |
- // If the buffer is valid it must be at least as long as the current builder contents! |
- ASSERT(m_buffer->length() >= m_length); |
- unsigned currentLength = m_length; |
- m_string = String(); |
- m_length = requiredLength; |
- return getBufferCharacters<CharType>() + currentLength; |
- } |
- |
- return appendUninitializedSlow<CharType>(requiredLength); |
-} |
- |
-// Make 'length' additional capacity be available in m_buffer, update m_string & m_length, |
-// return a pointer to the newly allocated storage. |
-template <typename CharType> |
-CharType* StringBuilder::appendUninitializedSlow(unsigned requiredLength) |
-{ |
- ASSERT(requiredLength); |
- |
- if (m_buffer) { |
- // If the buffer is valid it must be at least as long as the current builder contents! |
- ASSERT(m_buffer->length() >= m_length); |
- |
- reallocateBuffer<CharType>(std::max(requiredLength, std::max(minimumCapacity, m_buffer->length() * 2))); |
- } else { |
- ASSERT(m_string.length() == m_length); |
- allocateBuffer(m_length ? m_string.getCharacters<CharType>() : 0, std::max(requiredLength, std::max(minimumCapacity, m_length * 2))); |
- } |
- |
- CharType* result = getBufferCharacters<CharType>() + m_length; |
- m_length = requiredLength; |
- return result; |
-} |
- |
-void StringBuilder::append(const UChar* characters, unsigned length) |
-{ |
- if (!length) |
- return; |
- |
- ASSERT(characters); |
- |
- if (m_is8Bit) { |
- if (length == 1 && !(*characters & ~0xff)) { |
- // Append as 8 bit character |
- LChar lChar = static_cast<LChar>(*characters); |
- append(&lChar, 1); |
- return; |
- } |
- |
- // Calculate the new size of the builder after appending. |
- unsigned requiredLength = length + m_length; |
- RELEASE_ASSERT(requiredLength >= length); |
- |
- if (m_buffer) { |
- // If the buffer is valid it must be at least as long as the current builder contents! |
- ASSERT(m_buffer->length() >= m_length); |
- |
- allocateBufferUpConvert(m_buffer->characters8(), requiredLength); |
- } else { |
- ASSERT(m_string.length() == m_length); |
- allocateBufferUpConvert(m_string.isNull() ? 0 : m_string.characters8(), std::max(requiredLength, std::max(minimumCapacity, m_length * 2))); |
- } |
- |
- memcpy(m_bufferCharacters16 + m_length, characters, static_cast<size_t>(length) * sizeof(UChar)); |
- m_length = requiredLength; |
- } else |
- memcpy(appendUninitialized<UChar>(length), characters, static_cast<size_t>(length) * sizeof(UChar)); |
-} |
- |
-void StringBuilder::append(const LChar* characters, unsigned length) |
-{ |
- if (!length) |
- return; |
- ASSERT(characters); |
- |
- if (m_is8Bit) { |
- LChar* dest = appendUninitialized<LChar>(length); |
- if (length > 8) |
- memcpy(dest, characters, static_cast<size_t>(length) * sizeof(LChar)); |
- else { |
- const LChar* end = characters + length; |
- while (characters < end) |
- *(dest++) = *(characters++); |
- } |
- } else { |
- UChar* dest = appendUninitialized<UChar>(length); |
- const LChar* end = characters + length; |
- while (characters < end) |
- *(dest++) = *(characters++); |
- } |
-} |
- |
-void StringBuilder::appendNumber(int number) |
-{ |
- numberToStringSigned<StringBuilder>(number, this); |
-} |
- |
-void StringBuilder::appendNumber(unsigned int number) |
-{ |
- numberToStringUnsigned<StringBuilder>(number, this); |
-} |
- |
-void StringBuilder::appendNumber(long number) |
-{ |
- numberToStringSigned<StringBuilder>(number, this); |
-} |
- |
-void StringBuilder::appendNumber(unsigned long number) |
-{ |
- numberToStringUnsigned<StringBuilder>(number, this); |
-} |
- |
-void StringBuilder::appendNumber(long long number) |
-{ |
- numberToStringSigned<StringBuilder>(number, this); |
-} |
- |
-void StringBuilder::appendNumber(unsigned long long number) |
-{ |
- numberToStringUnsigned<StringBuilder>(number, this); |
-} |
- |
-bool StringBuilder::canShrink() const |
-{ |
- // Only shrink the buffer if it's less than 80% full. Need to tune this heuristic! |
- return m_buffer && m_buffer->length() > (m_length + (m_length >> 2)); |
-} |
- |
-void StringBuilder::shrinkToFit() |
-{ |
- if (canShrink()) { |
- if (m_is8Bit) |
- reallocateBuffer<LChar>(m_length); |
- else |
- reallocateBuffer<UChar>(m_length); |
- m_string = m_buffer; |
- m_buffer = 0; |
- } |
-} |
- |
-} // namespace WTF |