summaryrefslogtreecommitdiff
path: root/AK
diff options
context:
space:
mode:
Diffstat (limited to 'AK')
-rw-r--r--AK/Buffer.h14
-rw-r--r--AK/ByteBuffer.h8
-rw-r--r--AK/FileSystemPath.cpp2
-rw-r--r--AK/StringBuilder.cpp42
-rw-r--r--AK/StringBuilder.h7
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 };
};
}