platform_system_core/adb/adb_utils.h
Elliott Hughes b4dc7be6c5 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
2019-05-03 12:49:31 -07:00

143 lines
3.7 KiB
C++

/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <condition_variable>
#include <mutex>
#include <string>
#include <string_view>
#include <type_traits>
#include <vector>
#include <android-base/macros.h>
#include "adb.h"
void close_stdin();
bool getcwd(std::string* cwd);
bool directory_exists(const std::string& path);
// Return the user's home directory.
std::string adb_get_homedir_path();
// Return the adb user directory.
std::string adb_get_android_dir_path();
bool mkdirs(const std::string& path);
std::string escape_arg(const std::string& s);
std::string dump_hex(const void* ptr, size_t byte_count);
std::string dump_header(const amessage* msg);
std::string dump_packet(const char* name, const char* func, const apacket* p);
std::string perror_str(const char* msg);
[[noreturn]] void error_exit(const char* fmt, ...) __attribute__((__format__(__printf__, 1, 2)));
[[noreturn]] void perror_exit(const char* fmt, ...) __attribute__((__format__(__printf__, 1, 2)));
bool set_file_block_mode(int fd, bool block);
// Given forward/reverse targets, returns true if they look sane. If an error is found, fills
// |error| and returns false.
// Currently this only checks "tcp:" targets. Additional checking could be added for other targets
// if needed.
bool forward_targets_are_valid(const std::string& source, const std::string& dest,
std::string* error);
// A thread-safe blocking queue.
template <typename T>
class BlockingQueue {
std::mutex mutex;
std::condition_variable cv;
std::vector<T> queue;
public:
void Push(const T& t) {
{
std::unique_lock<std::mutex> lock(mutex);
queue.push_back(t);
}
cv.notify_one();
}
template <typename Fn>
void PopAll(Fn fn) {
std::vector<T> popped;
{
std::unique_lock<std::mutex> lock(mutex);
cv.wait(lock, [this]() { return !queue.empty(); });
popped = std::move(queue);
queue.clear();
}
for (const T& t : popped) {
fn(t);
}
}
};
std::string GetLogFilePath();
inline std::string_view StripTrailingNulls(std::string_view str) {
size_t n = 0;
for (auto it = str.rbegin(); it != str.rend(); ++it) {
if (*it != '\0') {
break;
}
++n;
}
str.remove_suffix(n);
return str;
}
// Base-10 stroll on a string_view.
template <typename T>
inline bool ParseUint(T* result, std::string_view str, std::string_view* remaining = nullptr) {
if (str.empty() || !isdigit(str[0])) {
return false;
}
T value = 0;
std::string_view::iterator it;
constexpr T max = std::numeric_limits<T>::max();
for (it = str.begin(); it != str.end() && isdigit(*it); ++it) {
if (value > max / 10) {
return false;
}
value *= 10;
T digit = *it - '0';
if (value > max - digit) {
return false;
}
value += digit;
}
*result = value;
if (remaining) {
*remaining = str.substr(it - str.begin());
} else {
return it == str.end();
}
return true;
}