diff options
author | Elliott Hughes <enh@google.com> | 2019-05-03 09:02:45 -0700 |
---|---|---|
committer | Luca Stefani <luca.stefani.ge1@gmail.com> | 2020-03-13 23:30:46 +0100 |
commit | 124e1a0ea611be51c8b514e663c4528f10e032bc (patch) | |
tree | 68c26e60b8859867dff7a61b85748e4ec8412253 | |
parent | a9981a8f6f58dc42a69b4f7e6d441def5dbd84e0 (diff) | |
download | system_core-124e1a0ea611be51c8b514e663c4528f10e032bc.tar.gz system_core-124e1a0ea611be51c8b514e663c4528f10e032bc.tar.bz2 system_core-124e1a0ea611be51c8b514e663c4528f10e032bc.zip |
libbase: add ConsumePrefix/ConsumeSuffix.
adb was already using ConsumePrefix, and now we have another would-be
user in cutils. (There appears to be one place in adb that should use
ConsumeSuffix, so I'm assuming we'll want that sooner or later.)
I've kept these inline because adb and google3's versions both were, and
I'm easily led.
Test: treehugger
Change-Id: I29d99032f6f6ccbfaefece59725db8afb02a4c87
-rw-r--r-- | adb/adb.cpp | 10 | ||||
-rw-r--r-- | adb/adb_utils.h | 8 | ||||
-rw-r--r-- | adb/daemon/abb.cpp | 5 | ||||
-rw-r--r-- | adb/daemon/services.cpp | 22 | ||||
-rw-r--r-- | adb/services.cpp | 10 | ||||
-rw-r--r-- | adb/sockets.cpp | 14 | ||||
-rw-r--r-- | base/include/android-base/strings.h | 17 | ||||
-rw-r--r-- | base/strings_test.cpp | 16 |
8 files changed, 65 insertions, 37 deletions
diff --git a/adb/adb.cpp b/adb/adb.cpp index 050ba49ad..d5e7be134 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp @@ -1052,9 +1052,9 @@ HostRequestResult handle_host_request(std::string_view service, TransportType ty // New transport selection protocol: // This is essentially identical to the previous version, except it returns the selected // transport id to the caller as well. - if (ConsumePrefix(&service, "tport:")) { + if (android::base::ConsumePrefix(&service, "tport:")) { legacy = false; - if (ConsumePrefix(&service, "serial:")) { + if (android::base::ConsumePrefix(&service, "serial:")) { serial_storage = service; serial = serial_storage.c_str(); } else if (service == "usb") { @@ -1068,7 +1068,7 @@ HostRequestResult handle_host_request(std::string_view service, TransportType ty // Selection by id is unimplemented, since you obviously already know the transport id // you're connecting to. } else { - if (ConsumePrefix(&service, "transport-id:")) { + if (android::base::ConsumePrefix(&service, "transport-id:")) { if (!ParseUint(&transport_id, service)) { SendFail(reply_fd, "invalid transport id"); return HostRequestResult::Handled; @@ -1079,7 +1079,7 @@ HostRequestResult handle_host_request(std::string_view service, TransportType ty type = kTransportLocal; } else if (service == "transport-any") { type = kTransportAny; - } else if (ConsumePrefix(&service, "transport:")) { + } else if (android::base::ConsumePrefix(&service, "transport:")) { serial_storage = service; serial = serial_storage.c_str(); } @@ -1220,7 +1220,7 @@ HostRequestResult handle_host_request(std::string_view service, TransportType ty } // Indicates a new emulator instance has started. - if (ConsumePrefix(&service, "emulator:")) { + if (android::base::ConsumePrefix(&service, "emulator:")) { unsigned int port; if (!ParseUint(&port, service)) { LOG(ERROR) << "received invalid port for emulator: " << service; diff --git a/adb/adb_utils.h b/adb/adb_utils.h index 5800a62f7..8b0dcee83 100644 --- a/adb/adb_utils.h +++ b/adb/adb_utils.h @@ -141,11 +141,3 @@ inline bool ParseUint(T* result, std::string_view str, std::string_view* remaini return true; } - -inline bool ConsumePrefix(std::string_view* str, std::string_view prefix) { - if (str->starts_with(prefix)) { - str->remove_prefix(prefix.size()); - return true; - } - return false; -} diff --git a/adb/daemon/abb.cpp b/adb/daemon/abb.cpp index eeac41a93..aa75bb193 100644 --- a/adb/daemon/abb.cpp +++ b/adb/daemon/abb.cpp @@ -17,6 +17,7 @@ #include <sys/wait.h> #include <android-base/cmsg.h> +#include <android-base/strings.h> #include <cmd.h> #include "adb.h" @@ -87,9 +88,9 @@ int main(int argc, char* const argv[]) { std::string_view name = data; auto protocol = SubprocessProtocol::kShell; - if (ConsumePrefix(&name, "abb:")) { + if (android::base::ConsumePrefix(&name, "abb:")) { protocol = SubprocessProtocol::kShell; - } else if (ConsumePrefix(&name, "abb_exec:")) { + } else if (android::base::ConsumePrefix(&name, "abb_exec:")) { protocol = SubprocessProtocol::kNone; } else { LOG(FATAL) << "Unknown command prefix for abb: " << data; diff --git a/adb/daemon/services.cpp b/adb/daemon/services.cpp index b0cc4509d..e6f44992d 100644 --- a/adb/daemon/services.cpp +++ b/adb/daemon/services.cpp @@ -223,13 +223,13 @@ asocket* daemon_service_to_socket(std::string_view name) { return create_jdwp_service_socket(); } else if (name == "track-jdwp") { return create_jdwp_tracker_service_socket(); - } else if (ConsumePrefix(&name, "sink:")) { + } else if (android::base::ConsumePrefix(&name, "sink:")) { uint64_t byte_count = 0; if (!ParseUint(&byte_count, name)) { return nullptr; } return new SinkSocket(byte_count); - } else if (ConsumePrefix(&name, "source:")) { + } else if (android::base::ConsumePrefix(&name, "source:")) { uint64_t byte_count = 0; if (!ParseUint(&byte_count, name)) { return nullptr; @@ -250,11 +250,11 @@ unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) { #if defined(__ANDROID__) if (name.starts_with("framebuffer:")) { return create_service_thread("fb", framebuffer_service); - } else if (ConsumePrefix(&name, "remount:")) { + } else if (android::base::ConsumePrefix(&name, "remount:")) { std::string arg(name); return create_service_thread("remount", std::bind(remount_service, std::placeholders::_1, arg)); - } else if (ConsumePrefix(&name, "reboot:")) { + } else if (android::base::ConsumePrefix(&name, "reboot:")) { std::string arg(name); return create_service_thread("reboot", std::bind(reboot_service, std::placeholders::_1, arg)); @@ -262,7 +262,7 @@ unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) { return create_service_thread("root", restart_root_service); } else if (name.starts_with("unroot:")) { return create_service_thread("unroot", restart_unroot_service); - } else if (ConsumePrefix(&name, "backup:")) { + } else if (android::base::ConsumePrefix(&name, "backup:")) { std::string cmd = "/system/bin/bu backup "; cmd += name; return StartSubprocess(cmd, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone); @@ -275,7 +275,7 @@ unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) { } else if (name.starts_with("enable-verity:")) { return create_service_thread("verity-off", std::bind(set_verity_enabled_state_service, std::placeholders::_1, true)); - } else if (ConsumePrefix(&name, "tcpip:")) { + } else if (android::base::ConsumePrefix(&name, "tcpip:")) { std::string str(name); int port; @@ -289,22 +289,22 @@ unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) { } #endif - if (ConsumePrefix(&name, "dev:")) { + if (android::base::ConsumePrefix(&name, "dev:")) { return unique_fd{unix_open(name, O_RDWR | O_CLOEXEC)}; - } else if (ConsumePrefix(&name, "jdwp:")) { + } else if (android::base::ConsumePrefix(&name, "jdwp:")) { pid_t pid; if (!ParseUint(&pid, name)) { return unique_fd{}; } return create_jdwp_connection_fd(pid); - } else if (ConsumePrefix(&name, "shell")) { + } else if (android::base::ConsumePrefix(&name, "shell")) { return ShellService(name, transport); - } else if (ConsumePrefix(&name, "exec:")) { + } else if (android::base::ConsumePrefix(&name, "exec:")) { return StartSubprocess(std::string(name), nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone); } else if (name.starts_with("sync:")) { return create_service_thread("sync", file_sync_service); - } else if (ConsumePrefix(&name, "reverse:")) { + } else if (android::base::ConsumePrefix(&name, "reverse:")) { return reverse_service(name, transport); } else if (name == "reconnect") { return create_service_thread( diff --git a/adb/services.cpp b/adb/services.cpp index 46cab6e5c..6185aa68a 100644 --- a/adb/services.cpp +++ b/adb/services.cpp @@ -202,7 +202,7 @@ asocket* host_service_to_socket(std::string_view name, std::string_view serial, return create_device_tracker(false); } else if (name == "track-devices-l") { return create_device_tracker(true); - } else if (ConsumePrefix(&name, "wait-for-")) { + } else if (android::base::ConsumePrefix(&name, "wait-for-")) { std::shared_ptr<state_info> sinfo = std::make_shared<state_info>(); if (sinfo == nullptr) { fprintf(stderr, "couldn't allocate state_info: %s", strerror(errno)); @@ -212,11 +212,11 @@ asocket* host_service_to_socket(std::string_view name, std::string_view serial, sinfo->serial = serial; sinfo->transport_id = transport_id; - if (ConsumePrefix(&name, "local")) { + if (android::base::ConsumePrefix(&name, "local")) { sinfo->transport_type = kTransportLocal; - } else if (ConsumePrefix(&name, "usb")) { + } else if (android::base::ConsumePrefix(&name, "usb")) { sinfo->transport_type = kTransportUsb; - } else if (ConsumePrefix(&name, "any")) { + } else if (android::base::ConsumePrefix(&name, "any")) { sinfo->transport_type = kTransportAny; } else { return nullptr; @@ -243,7 +243,7 @@ asocket* host_service_to_socket(std::string_view name, std::string_view serial, unique_fd fd = create_service_thread( "wait", [sinfo](unique_fd fd) { wait_for_state(std::move(fd), sinfo.get()); }); return create_local_socket(std::move(fd)); - } else if (ConsumePrefix(&name, "connect:")) { + } else if (android::base::ConsumePrefix(&name, "connect:")) { std::string host(name); unique_fd fd = create_service_thread( "connect", std::bind(connect_service, std::placeholders::_1, host)); diff --git a/adb/sockets.cpp b/adb/sockets.cpp index 8a2bf9a2c..75993b3ce 100644 --- a/adb/sockets.cpp +++ b/adb/sockets.cpp @@ -31,6 +31,8 @@ #include <string> #include <vector> +#include <android-base/strings.h> + #if !ADB_HOST #include <android-base/properties.h> #include <log/log_properties.h> @@ -755,26 +757,26 @@ static int smart_socket_enqueue(asocket* s, apacket::payload_type data) { #if ADB_HOST service = std::string_view(s->smart_socket_data).substr(4); - if (ConsumePrefix(&service, "host-serial:")) { + if (android::base::ConsumePrefix(&service, "host-serial:")) { // serial number should follow "host:" and could be a host:port string. if (!internal::parse_host_service(&serial, &service, service)) { LOG(ERROR) << "SS(" << s->id << "): failed to parse host service: " << service; goto fail; } - } else if (ConsumePrefix(&service, "host-transport-id:")) { + } else if (android::base::ConsumePrefix(&service, "host-transport-id:")) { if (!ParseUint(&transport_id, service, &service)) { LOG(ERROR) << "SS(" << s->id << "): failed to parse host transport id: " << service; return -1; } - if (!ConsumePrefix(&service, ":")) { + if (!android::base::ConsumePrefix(&service, ":")) { LOG(ERROR) << "SS(" << s->id << "): host-transport-id without command"; return -1; } - } else if (ConsumePrefix(&service, "host-usb:")) { + } else if (android::base::ConsumePrefix(&service, "host-usb:")) { type = kTransportUsb; - } else if (ConsumePrefix(&service, "host-local:")) { + } else if (android::base::ConsumePrefix(&service, "host-local:")) { type = kTransportLocal; - } else if (ConsumePrefix(&service, "host:")) { + } else if (android::base::ConsumePrefix(&service, "host:")) { type = kTransportAny; } else { service = std::string_view{}; diff --git a/base/include/android-base/strings.h b/base/include/android-base/strings.h index 8e9716f9f..b1c22c9f7 100644 --- a/base/include/android-base/strings.h +++ b/base/include/android-base/strings.h @@ -18,6 +18,7 @@ #include <sstream> #include <string> +#include <string_view> #include <vector> namespace android { @@ -68,5 +69,21 @@ bool EndsWithIgnoreCase(std::string_view s, std::string_view suffix); // Tests whether 'lhs' equals 'rhs', ignoring case. bool EqualsIgnoreCase(std::string_view lhs, std::string_view rhs); +// Removes `prefix` from the start of the given string and returns true (if +// it was present), false otherwise. +inline bool ConsumePrefix(std::string_view* s, std::string_view prefix) { + if (!StartsWith(*s, prefix)) return false; + s->remove_prefix(prefix.size()); + return true; +} + +// Removes `suffix` from the end of the given string and returns true (if +// it was present), false otherwise. +inline bool ConsumeSuffix(std::string_view* s, std::string_view suffix) { + if (!EndsWith(*s, suffix)) return false; + s->remove_suffix(suffix.size()); + return true; +} + } // namespace base } // namespace android diff --git a/base/strings_test.cpp b/base/strings_test.cpp index 9d740947e..ca3c0b83e 100644 --- a/base/strings_test.cpp +++ b/base/strings_test.cpp @@ -295,3 +295,19 @@ TEST(strings, EqualsIgnoreCase) { TEST(strings, ubsan_28729303) { android::base::Split("/dev/null", ":"); } + +TEST(strings, ConsumePrefix) { + std::string_view s{"foo.bar"}; + ASSERT_FALSE(android::base::ConsumePrefix(&s, "bar.")); + ASSERT_EQ("foo.bar", s); + ASSERT_TRUE(android::base::ConsumePrefix(&s, "foo.")); + ASSERT_EQ("bar", s); +} + +TEST(strings, ConsumeSuffix) { + std::string_view s{"foo.bar"}; + ASSERT_FALSE(android::base::ConsumeSuffix(&s, ".foo")); + ASSERT_EQ("foo.bar", s); + ASSERT_TRUE(android::base::ConsumeSuffix(&s, ".bar")); + ASSERT_EQ("foo", s); +} |