diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-01-18 03:27:51 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-01-18 03:27:51 +0100 |
commit | 9d7da26b4ecde03255df2572d5bc9fd23da0ff7c (patch) | |
tree | 68ca951b0933b2b2a622dd73ebc2645502cb1204 /AK | |
parent | 074edffc4411c392dc9df304ff6335cdb8fdd8de (diff) | |
download | serenity-9d7da26b4ecde03255df2572d5bc9fd23da0ff7c.zip |
StringBuilder: Use a ByteBuffer internally instead of a Vector<String>.
Diffstat (limited to 'AK')
-rw-r--r-- | AK/Buffer.h | 14 | ||||
-rw-r--r-- | AK/ByteBuffer.h | 8 | ||||
-rw-r--r-- | AK/FileSystemPath.cpp | 2 | ||||
-rw-r--r-- | AK/StringBuilder.cpp | 42 | ||||
-rw-r--r-- | AK/StringBuilder.h | 7 |
5 files changed, 47 insertions, 26 deletions
diff --git a/AK/Buffer.h b/AK/Buffer.h index 3c1feb34c5..37fef0ea28 100644 --- a/AK/Buffer.h +++ b/AK/Buffer.h @@ -47,6 +47,8 @@ public: m_size = size; } + void grow(size_t size); + private: enum ConstructionMode { Uninitialized, Copy, Wrap, Adopt }; explicit Buffer(size_t); // For ConstructionMode=Uninitialized @@ -87,7 +89,19 @@ inline Buffer<T>::Buffer(T* elements, size_t size, ConstructionMode mode) } else if (mode == Wrap) { m_owned = false; } +} +template<typename T> +inline void Buffer<T>::grow(size_t size) +{ + ASSERT(size > m_size); + ASSERT(m_owned); + T* new_elements = static_cast<T*>(kmalloc(size * sizeof(T))); + memcpy(new_elements, m_elements, m_size * sizeof(T)); + T* old_elements = m_elements; + m_elements = new_elements; + m_size = size; + kfree(old_elements); } template<typename T> diff --git a/AK/ByteBuffer.h b/AK/ByteBuffer.h index 62075563e6..9f776c45a8 100644 --- a/AK/ByteBuffer.h +++ b/AK/ByteBuffer.h @@ -73,6 +73,14 @@ public: return copy(offset_pointer(offset), size); } + void grow(size_t size) + { + if (!m_impl) + m_impl = Buffer<byte>::create_uninitialized(size); + else + m_impl->grow(size); + } + private: explicit ByteBuffer(RetainPtr<Buffer<byte>>&& impl) : m_impl(move(impl)) diff --git a/AK/FileSystemPath.cpp b/AK/FileSystemPath.cpp index 5f467c8594..232c05ecb3 100644 --- a/AK/FileSystemPath.cpp +++ b/AK/FileSystemPath.cpp @@ -38,7 +38,7 @@ bool FileSystemPath::canonicalize(bool resolve_symbolic_links) StringBuilder builder; for (auto& cpart : canonical_parts) { builder.append('/'); - builder.append(move(cpart)); + builder.append(cpart); } m_string = builder.build(); return true; diff --git a/AK/StringBuilder.cpp b/AK/StringBuilder.cpp index 558f071bd4..0e155df72c 100644 --- a/AK/StringBuilder.cpp +++ b/AK/StringBuilder.cpp @@ -1,22 +1,30 @@ #include "StringBuilder.h" #include <LibC/stdarg.h> #include "printf.cpp" +#include <AK/StdLibExtras.h> namespace AK { -void StringBuilder::append(String&& str) +inline void StringBuilder::will_append(size_t size) { - m_strings.append(move(str)); + if ((m_length + size) > m_buffer.size()) + m_buffer.grow(max(16u, m_buffer.size() * 2 + size)); } void StringBuilder::append(const String& str) { - m_strings.append(str); + if (str.is_empty()) + return; + will_append(str.length()); + memcpy(m_buffer.pointer() + m_length, str.characters(), str.length()); + m_length += str.length(); } void StringBuilder::append(char ch) { - m_strings.append(StringImpl::create(&ch, 1)); + will_append(1); + m_buffer.pointer()[m_length] = ch; + m_length += 1; } void StringBuilder::appendf(const char* fmt, ...) @@ -29,27 +37,15 @@ void StringBuilder::appendf(const char* fmt, ...) va_end(ap); } +ByteBuffer StringBuilder::to_byte_buffer() +{ + m_buffer.trim(m_length); + return m_buffer; +} + String StringBuilder::build() { - auto strings = move(m_strings); - if (strings.is_empty()) - return String::empty(); - - size_t sizeNeeded = 0; - for (auto& string : strings) - sizeNeeded += string.length(); - - char* buffer; - auto impl = StringImpl::create_uninitialized(sizeNeeded, buffer); - if (!impl) - return String(); - - for (auto& string : strings) { - memcpy(buffer, string.characters(), string.length()); - buffer += string.length(); - } - *buffer = '\0'; - return String(move(impl)); + return String((const char*)m_buffer.pointer(), m_length); } } diff --git a/AK/StringBuilder.h b/AK/StringBuilder.h index 624e71b206..434f7a917b 100644 --- a/AK/StringBuilder.h +++ b/AK/StringBuilder.h @@ -11,14 +11,17 @@ public: ~StringBuilder() { } void append(const String&); - void append(String&&); void append(char); void appendf(const char*, ...); String build(); + ByteBuffer to_byte_buffer(); private: - Vector<String> m_strings; + void will_append(size_t); + + ByteBuffer m_buffer; + size_t m_length { 0 }; }; } |