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
This commit is contained in:
parent
56311071fe
commit
b4dc7be6c5
8 changed files with 65 additions and 37 deletions
10
adb/adb.cpp
10
adb/adb.cpp
|
@ -1048,9 +1048,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") {
|
||||
|
@ -1064,7 +1064,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;
|
||||
|
@ -1075,7 +1075,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();
|
||||
}
|
||||
|
@ -1216,7 +1216,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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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{};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue