diff --git a/AK/AKString.h b/AK/AKString.h index 27efb800515..2370a2bd4d6 100644 --- a/AK/AKString.h +++ b/AK/AKString.h @@ -118,7 +118,16 @@ public: } ByteBuffer to_byte_buffer() const; - static String from_byte_buffer(const ByteBuffer&, ShouldChomp = NoChomp); + + template + static String copy(const BufferType& buffer, ShouldChomp should_chomp = NoChomp) + { + if (buffer.is_null()) + return { }; + if (buffer.is_empty()) + return empty(); + return String((const char*)buffer.data(), buffer.size(), should_chomp); + } static String format(const char*, ...); diff --git a/AK/ByteBuffer.h b/AK/ByteBuffer.h index 55d09b37df7..bea90cb450c 100644 --- a/AK/ByteBuffer.h +++ b/AK/ByteBuffer.h @@ -104,6 +104,9 @@ public: bool is_empty() const { return !m_impl || m_impl->is_empty(); } ssize_t size() const { return m_impl ? m_impl->size() : 0; } + byte* data() { return pointer(); } + const byte* data() const { return pointer(); } + byte* pointer() { return m_impl ? m_impl->pointer() : nullptr; } const byte* pointer() const { return m_impl ? m_impl->pointer() : nullptr; } diff --git a/AK/String.cpp b/AK/String.cpp index 0e1fce18c73..a87473d3237 100644 --- a/AK/String.cpp +++ b/AK/String.cpp @@ -122,15 +122,6 @@ ByteBuffer String::to_byte_buffer() const return ByteBuffer::copy(reinterpret_cast(characters()), length()); } -String String::from_byte_buffer(const ByteBuffer& buffer, ShouldChomp should_chomp) -{ - if (buffer.is_null()) - return { }; - if (buffer.is_empty()) - return empty(); - return String((const char*)buffer.pointer(), buffer.size(), should_chomp); -} - // FIXME: Duh. int String::to_int(bool& ok) const { diff --git a/AK/Vector.h b/AK/Vector.h index 1ddd9f032c7..5639ca7aa91 100644 --- a/AK/Vector.h +++ b/AK/Vector.h @@ -93,6 +93,8 @@ public: return false; } + // NOTE: Vector::is_null() exists for the benefit of String::copy(). + bool is_null() const { return is_empty(); } bool is_empty() const { return size() == 0; } int size() const { return m_size; } int capacity() const { return m_capacity; } diff --git a/Applications/IRCClient/IRCClient.cpp b/Applications/IRCClient/IRCClient.cpp index 67f1854ba19..c83a5183c8f 100644 --- a/Applications/IRCClient/IRCClient.cpp +++ b/Applications/IRCClient/IRCClient.cpp @@ -150,10 +150,10 @@ void IRCClient::process_line(ByteBuffer&& line) } } if (!current_parameter.is_empty()) - msg.arguments.append(String(current_parameter.data(), current_parameter.size())); - msg.prefix = String(prefix.data(), prefix.size()); - msg.command = String(command.data(), command.size()); - handle(msg, String(m_line_buffer.data(), m_line_buffer.size())); + msg.arguments.append(String::copy(current_parameter)); + msg.prefix = String::copy(prefix); + msg.command = String::copy(command); + handle(msg); } void IRCClient::send(const String& text) @@ -195,7 +195,7 @@ void IRCClient::send_whois(const String& nick) send(String::format("WHOIS %s\r\n", nick.characters())); } -void IRCClient::handle(const Message& msg, const String&) +void IRCClient::handle(const Message& msg) { #ifdef IRC_DEBUG printf("IRCClient::execute: prefix='%s', command='%s', arguments=%d\n", diff --git a/Applications/IRCClient/IRCClient.h b/Applications/IRCClient/IRCClient.h index 2ee82d2bb21..4502cb0b5f1 100644 --- a/Applications/IRCClient/IRCClient.h +++ b/Applications/IRCClient/IRCClient.h @@ -106,7 +106,7 @@ private: void handle_rpl_namreply(const Message&); void handle_privmsg(const Message&); void handle_nick(const Message&); - void handle(const Message&, const String& verbatim); + void handle(const Message&); void handle_user_command(const String&); void on_socket_connected(); @@ -117,7 +117,6 @@ private: CTCPSocket* m_socket { nullptr }; String m_nickname; - Vector m_line_buffer; OwnPtr m_notifier; HashMap> m_channels; HashMap> m_queries; diff --git a/Applications/Terminal/Terminal.cpp b/Applications/Terminal/Terminal.cpp index 53ceef4cdf6..b95ba07b308 100644 --- a/Applications/Terminal/Terminal.cpp +++ b/Applications/Terminal/Terminal.cpp @@ -393,13 +393,13 @@ void Terminal::execute_xterm_command() { m_final = '@'; bool ok; - unsigned value = parse_uint(String((const char*)m_xterm_param1.data(), m_xterm_param1.size()), ok); + unsigned value = parse_uint(String::copy(m_xterm_param1), ok); if (ok) { switch (value) { case 0: case 1: case 2: - set_window_title(String((const char*)m_xterm_param2.data(), m_xterm_param2.size())); + set_window_title(String::copy(m_xterm_param2)); break; default: unimplemented_xterm_escape(); @@ -413,7 +413,7 @@ void Terminal::execute_xterm_command() void Terminal::execute_escape_sequence(byte final) { m_final = final; - auto paramparts = String((const char*)m_parameters.data(), m_parameters.size()).split(';'); + auto paramparts = String::copy(m_parameters).split(';'); ParamVector params; for (auto& parampart : paramparts) { bool ok; diff --git a/Applications/TextEditor/main.cpp b/Applications/TextEditor/main.cpp index 99057318944..43dcb6411b2 100644 --- a/Applications/TextEditor/main.cpp +++ b/Applications/TextEditor/main.cpp @@ -41,7 +41,7 @@ int main(int argc, char** argv) fprintf(stderr, "Opening %s: %s\n", path.characters(), file.error_string()); return 1; } - text_editor->set_text(String::from_byte_buffer(file.read_all())); + text_editor->set_text(String::copy(file.read_all())); } auto new_action = GAction::create("New document", { Mod_Ctrl, Key_N }, GraphicsBitmap::load_from_file("/res/icons/16x16/new.png"), [] (const GAction&) { diff --git a/Kernel/TTY/VirtualConsole.cpp b/Kernel/TTY/VirtualConsole.cpp index 995f9b2720d..16afe5e3b8c 100644 --- a/Kernel/TTY/VirtualConsole.cpp +++ b/Kernel/TTY/VirtualConsole.cpp @@ -320,7 +320,7 @@ void VirtualConsole::escape$J(const Vector& params) void VirtualConsole::execute_escape_sequence(byte final) { - auto paramparts = String((const char*)m_parameters.data(), m_parameters.size()).split(';'); + auto paramparts = String::copy(m_parameters).split(';'); Vector params; for (auto& parampart : paramparts) { bool ok; diff --git a/LibCore/CHttpJob.cpp b/LibCore/CHttpJob.cpp index 1798005e9ba..f9a9a08f3b5 100644 --- a/LibCore/CHttpJob.cpp +++ b/LibCore/CHttpJob.cpp @@ -17,7 +17,7 @@ void CHttpJob::on_socket_connected() { auto raw_request = m_request.to_raw_request(); #if 0 - printf("raw_request:\n%s\n", String::from_byte_buffer(raw_request).characters()); + printf("raw_request:\n%s\n", String::copy(raw_request).characters()); #endif bool success = m_socket->send(raw_request); @@ -35,7 +35,7 @@ void CHttpJob::on_socket_connected() printf("Expected HTTP status\n"); return deferred_invoke([this](auto&){ did_fail(CNetworkJob::Error::TransmissionFailed); }); } - auto parts = String::from_byte_buffer(line, Chomp).split(' '); + auto parts = String::copy(line, Chomp).split(' '); if (parts.size() < 3) { printf("Expected 3-part HTTP status, got '%s'\n", line.pointer()); return deferred_invoke([this](auto&){ did_fail(CNetworkJob::Error::ProtocolFailed); }); @@ -57,7 +57,7 @@ void CHttpJob::on_socket_connected() printf("Expected HTTP header\n"); return did_fail(CNetworkJob::Error::ProtocolFailed); } - auto chomped_line = String::from_byte_buffer(line, Chomp); + auto chomped_line = String::copy(line, Chomp); if (chomped_line.is_empty()) { m_state = State::InBody; continue; diff --git a/Servers/LookupServer/main.cpp b/Servers/LookupServer/main.cpp index 45aeabb7f30..5cc3cabee2f 100644 --- a/Servers/LookupServer/main.cpp +++ b/Servers/LookupServer/main.cpp @@ -265,7 +265,7 @@ Vector lookup(const String& hostname, bool& did_timeout) static String parse_dns_name(const byte* data, int& offset, int max_offset) { - Vector buf; + Vector buf; while (offset < max_offset) { byte ch = data[offset]; if (ch == '\0') { @@ -283,5 +283,5 @@ static String parse_dns_name(const byte* data, int& offset, int max_offset) buf.append('.'); offset += ch + 1; } - return String(buf.data(), buf.size()); + return String::copy(buf); }