AK: Add String::copy(BufferType) helper.

This will create a String from any BufferType that has data() and size().
This commit is contained in:
Andreas Kling 2019-04-20 14:13:40 +02:00
parent 5eedb22834
commit ab94a6be00
11 changed files with 31 additions and 27 deletions

View file

@ -118,7 +118,16 @@ public:
}
ByteBuffer to_byte_buffer() const;
static String from_byte_buffer(const ByteBuffer&, ShouldChomp = NoChomp);
template<typename BufferType>
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*, ...);

View file

@ -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; }

View file

@ -122,15 +122,6 @@ ByteBuffer String::to_byte_buffer() const
return ByteBuffer::copy(reinterpret_cast<const byte*>(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
{

View file

@ -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; }

View file

@ -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",

View file

@ -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<char> m_line_buffer;
OwnPtr<CNotifier> m_notifier;
HashMap<String, RetainPtr<IRCChannel>> m_channels;
HashMap<String, RetainPtr<IRCQuery>> m_queries;

View file

@ -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;

View file

@ -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&) {

View file

@ -320,7 +320,7 @@ void VirtualConsole::escape$J(const Vector<unsigned>& 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<unsigned> params;
for (auto& parampart : paramparts) {
bool ok;

View file

@ -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;

View file

@ -265,7 +265,7 @@ Vector<IPv4Address> lookup(const String& hostname, bool& did_timeout)
static String parse_dns_name(const byte* data, int& offset, int max_offset)
{
Vector<char> buf;
Vector<char, 128> 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);
}