Android native development: system/core/base

1. chrono_utils.h

Cross-platform, providing different implementations for Linux and Win/Darwin.

class boot_clock;
class Timer;

2. cmsg.h

Linux provides cmsg(3) series macros to manage control messages related to local sockets.
The packaging of cmsg avoids prone to errors.

ssize_t SendFileDescriptorVector(borrowed_fd sock, const void* data, size_t len,
                                 const std::vector<int>& fds);
ssize_t ReceiveFileDescriptorVector(borrowed_fd sock, void* data, size_t len, size_t max_fds,
                                    std::vector<android::base::unique_fd>* fds);

template <typename... Args>
ssize_t SendFileDescriptors(borrowed_fd sock, const void* data, size_t len, Args&&... sent_fds);

template <typename... Args>
ssize_t ReceiveFileDescriptors(borrowed_fd sock, void* data, size_t len, Args&&... received_fds);

3. collections.h

Auxiliary function that puts the variable-length parameters of the template into the collection container.

// Use as follows:
   template <typename... Args>
   std::vector<int> CreateVector(Args&&... args) {
    
    
     std::vector<int> result;
     Append(result, std::forward<Args>(args)...);
     return result;
   }

template <typename CollectionType, typename T>
void Append(CollectionType& collection, T&& arg);

template <typename CollectionType, typename T, typename... Args>
void Append(CollectionType& collection, T&& arg, Args&&... args);

template <typename T, typename Arg, typename... Args>
void AssertType(Arg&&);

template <typename T, typename Arg, typename... Args>
void AssertType(Arg&&, Args&&... args);

4. endian.h

Some macro definitions encapsulate the function __builtin_bswap16/32/64.
A cross-platform equivalent of the standard C library <sys/endian.h>.

5. errno_restorer.h

Temporarily save errno and restore it after the scope ends.

class ErrnoRestorer {
    
    
 public:
  ErrnoRestorer() : saved_errno_(errno) {
    
    }
  ~ErrnoRestorer() {
    
     errno = saved_errno_; }
 private:
  const int saved_errno_;
};

6. errors.h

Cross-platform support for converting error codes to strings, calling strerror on Linux.

std::string SystemErrorCodeToString(int error_code);

7. expected.h

Implements std::expected.
When std::expected officially enters the C++ standard, this implementation is deleted, and android::base::expected is only used as an alias of std::expected.

using android::base::expected;
using android::base::unexpected;

expected<double,std::string> safe_divide(double i, double j) {
    
    
  if (j == 0) return unexpected("divide by zero");
  else return i / j;
}

void test() {
    
    
  auto q = safe_divide(10, 0);
  if (q) {
    
     printf("%f\n", q.value()); }
  else {
    
     printf("%s\n", q.error().c_str()); }
}

8. file.h

Helper functions for file operations.

class TemporaryFile;

class TemporaryDir;

bool ReadFdToString(borrowed_fd fd, std::string* content);
bool ReadFileToString(const std::string& path, std::string* content,
                      bool follow_symlinks = false);

bool WriteStringToFile(const std::string& content, const std::string& path,
                       bool follow_symlinks = false);
bool WriteStringToFd(const std::string& content, borrowed_fd fd);

bool WriteStringToFile(const std::string& content, const std::string& path,
                       mode_t mode, uid_t owner, gid_t group,
                       bool follow_symlinks = false);

bool ReadFully(borrowed_fd fd, void* data, size_t byte_count);

bool ReadFullyAtOffset(borrowed_fd fd, void* data, size_t byte_count, off64_t offset);
bool WriteFully(borrowed_fd fd, const void* data, size_t byte_count);

bool RemoveFileIfExists(const std::string& path, std::string* err = nullptr);

bool Realpath(const std::string& path, std::string* result);
bool Readlink(const std::string& path, std::string* result);

std::string GetExecutablePath();
std::string GetExecutableDirectory();

std::string Basename(const std::string& path);
std::string Dirname(const std::string& path);

9. format.h

Through this header file, the fmtlib library can be introduced. This library is statically linked into libbase.
The following are some usage examples, which are available in Android native code.

// We include fmtlib here as an alias, since libbase will have fmtlib statically linked already.
// It is accessed through its normal fmt:: namespace.

#include <android-base/format.h>

std::string msg = fmt::format("hello {} by fmt", "world");

std::string message = fmt::sprintf("The answer is %d", 42);
fmt::fprintf(stderr, "Don't %s!", "panic");
fmt::printf("Elapsed time: %.2f seconds", 1.23);

std::vector<int> v = {
    
    1, 2, 3};
fmt::print("{}", fmt::join(v, ", "));
// Output: "1, 2, 3"

std::string answer = fmt::to_string(42);

std::vector<char> out;
fmt::format_to(std::back_inserter(out), "{}", 42);

// User-defined literal equivalent of :func:`fmt::format`.
using namespace fmt::literals;
std::string message = "The answer is {}"_format(42);
fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23);

// Constructs a compile-time format string.
// A compile-time error because 'd' is an invalid specifier for strings.
std::string s = format(FMT_STRING("{:d}"), "foo");

10. logging.h

The log encapsulated by the C++ stream interface.
Android outputs to logcat, and host outputs to stderr. Output can be set with SetLogger.
By default, the process name is used as tag, and the macro LOG_TAG can also be defined (before the include header file).

Some assertion macros are also provided. CHECK, CHECK_EQ

// To log:
LOG(INFO) << "Some text; " << some_value;

PLOG(ERROR) << "Write failed"; // 类似perror()
// `Write failed: I/O error`.

CHECK(must_be_true);
CHECK_EQ(a, b) << z_is_interesting_too;

// Log to the kernel log (dmesg).
void KernelLogger(LogId, LogSeverity, const char*, const char*, unsigned int, const char*);
// Log to stderr in the full logcat format (with pid/tid/time/tag details).
void StderrLogger(LogId, LogSeverity, const char*, const char*, unsigned int, const char*);
// Log just the message to stdout/stderr (without pid/tid/time/tag details).
// Useful for replacing printf(3)/perror(3)/err(3)/error(3) in command-line tools.
void StdioLogger(LogId, LogSeverity, const char*, const char*, unsigned int, const char*);

void DefaultAborter(const char* abort_message);
void SetDefaultTag(const std::string& tag);

void InitLogging(char* argv[],
                 LogFunction&& logger = INIT_LOGGING_DEFAULT_LOGGER,
                 AbortFunction&& aborter = DefaultAborter);

// Replace the current logger.
void SetLogger(LogFunction&& logger);
// Replace the current aborter.
void SetAborter(AbortFunction&& aborter);

11. macros.h

Several macro definitions.

#define TEMP_FAILURE_RETRY(exp)            
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName)

#define arraysize(array) (sizeof(ArraySizeHelper(array)))
#define SIZEOF_MEMBER(t, f) sizeof(std::declval<t>().f)

#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))

#define WARN_UNUSED __attribute__((warn_unused_result))

#define ATTRIBUTE_UNUSED __attribute__((__unused__))
#define FALLTHROUGH_INTENDED [[clang::fallthrough]]  // NOLINT

12. mapped_file.h

Provide filemapping cross-platform implementation.

class MappedFile {
    
    
 public:
  static std::unique_ptr<MappedFile> FromFd(borrowed_fd fd, off64_t offset, size_t length,
  static std::unique_ptr<MappedFile> FromOsHandle(os_handle h, off64_t offset, size_t length,
                                                  int prot);
  MappedFile(MappedFile&& other);
  MappedFile& operator=(MappedFile&& other);

  char* data() const {
    
     return base_ + offset_; }
  size_t size() const {
    
     return size_; }

 private:
  MappedFile(char* base, size_t size, size_t offset) : base_(base), size_(size), offset_(offset) {
    
    }
};

13. memory.h

2 memcpy helper functions.

// Use memcpy for access to unaligned data on targets with alignment
// restrictions.  The compiler will generate appropriate code to access these
// structures without generating alignment exceptions.
template <typename T>
static inline T get_unaligned(const void* address) {
    
    
  T result;
  memcpy(&result, address, sizeof(T));
  return result;
}

template <typename T>
static inline void put_unaligned(void* address, T v) {
    
    
  memcpy(address, &v, sizeof(T));
}

14. no_destructor.h

TODO: I don't quite understand what is the purpose of this class? ?
Initialize an object of type T on the stack space using placement new.

template <typename T>
class NoDestructor;

15. off64_t.h

/** Mac OS has always had a 64-bit off_t, so it doesn't have off64_t. */
typedef off_t off64_t;

16. parsebool.h

Parse string into bool type (ParseBoolResult encapsulation).

ParseBoolResult ParseBool(std::string_view s);

17. parsedouble.h

Parses string into double type.
TODO: Are they all static functions? Can't be called externally?

template <typename T, T (*strtox)(const char* str, char** endptr)>
static inline bool ParseFloatingPoint(const char* s, T* out, T min, T max);

static inline bool ParseDouble(const char* s, double* out,
                               double min = std::numeric_limits<double>::lowest(),
                               double max = std::numeric_limits<double>::max());

static inline bool ParseDouble(const std::string& s, double* out,
                               double min = std::numeric_limits<double>::lowest(),
                               double max = std::numeric_limits<double>::max());

static inline bool ParseFloat(const char* s, float* out,
                              float min = std::numeric_limits<float>::lowest(),
                              float max = std::numeric_limits<float>::max());

static inline bool ParseFloat(const std::string& s, float* out,
                              float min = std::numeric_limits<float>::lowest(),
                              float max = std::numeric_limits<float>::max());

18. parseint.h

string parsing int helper function.

template <typename T>
bool ParseUint(const char* s, T* out, T max = std::numeric_limits<T>::max(),
               bool allow_suffixes = false);

template <typename T>
bool ParseUint(const std::string& s, T* out, T max = std::numeric_limits<T>::max(),
               bool allow_suffixes = false);

template <typename T>
bool ParseByteCount(const char* s, T* out, T max = std::numeric_limits<T>::max());

template <typename T>
bool ParseByteCount(const std::string& s, T* out, T max = std::numeric_limits<T>::max());

template <typename T>
bool ParseInt(const char* s, T* out,
              T min = std::numeric_limits<T>::min(),
              T max = std::numeric_limits<T>::max())

template <typename T>
bool ParseInt(const std::string& s, T* out,
              T min = std::numeric_limits<T>::min(),
              T max = std::numeric_limits<T>::max());

19. parsenetaddress.h

String parsing network address helper function.

bool ParseNetAddress(const std::string& address, std::string* host, int* port,
                     std::string* canonical_address, std::string* error);

20. process.h

Traverse the /proc directory to get all pids.

class AllPids {
    
    
  class PidIterator {
    
    
   public:
    PidIterator(DIR* dir) : dir_(dir, closedir) {
    
     Increment(); }
    PidIterator& operator++();
  };

 public:
  PidIterator begin() {
    
     return opendir("/proc"); }
  PidIterator end() {
    
     return nullptr; }
};

21. properties.h

Encapsulate read and write property interface.

std::string GetProperty(const std::string& key, const std::string& default_value);

bool GetBoolProperty(const std::string& key, bool default_value);

template <typename T> T GetIntProperty(const std::string& key,
                                       T default_value,
                                       T min = std::numeric_limits<T>::min(),
                                       T max = std::numeric_limits<T>::max());

template <typename T> T GetUintProperty(const std::string& key,
                                        T default_value,
                                        T max = std::numeric_limits<T>::max());

bool SetProperty(const std::string& key, const std::string& value);

bool WaitForProperty(const std::string& key, const std::string& expected_value,
                     std::chrono::milliseconds relative_timeout = std::chrono::milliseconds::max());

bool WaitForPropertyCreation(const std::string& key, std::chrono::milliseconds relative_timeout =
                                                         std::chrono::milliseconds::max());

// Cached system property lookup. For code that needs to read the same property multiple times,
// this class helps optimize those lookups.
class CachedProperty;

22. result.h

1) Result<T>Contains a value of type T (similar to optional<T>access), or contains error information of type ResultError (via Result<T>::error()access)
2) ResultError contains a string type of information and errno, and can be output directly with ostream.
3) ResultError<void>For functions that do not return a value, the function returns successfully, return { }.
4) The returned one ResultError<T>can automatically construct ResultError by returning an object of type T, or any object that can be converted to type T.
5) Error and ErrnoError are used to create errors Result<T>, and Errorf and ErrnoErrorf format and output error messages.
6) The ResultError type can be directly constructed Result<T>,Result<U>.error() -> Result<T>

Result<U> CalculateResult(const T& input) {
    
    
  U output;
  if (!SomeOtherCppFunction(input, &output)) {
    
    
    return Errorf("SomeOtherCppFunction {} failed", input);
  }
  if (!c_api_function(output)) {
    
    
    return ErrnoErrorf("c_api_function {} failed", output);
  }
  return output;
}

auto output = CalculateResult(input);
if (!output) return Error() << "CalculateResult failed: " << output.error();
UseOutput(*output);

23. scopeguard.h

Provides an RAII helper class that ensures that the specified function (object) is called when the scope ends.

// ScopeGuard ensures that the specified functor is executed no matter how the
// current scope exits.
template <typename F>
class ScopeGuard {
    
    
 public:
  ScopeGuard(F&& f) : f_(std::forward<F>(f)), active_(true) {
    
    }

  ScopeGuard(ScopeGuard&& that) noexcept : f_(std::move(that.f_)), active_(that.active_) {
    
    
    that.active_ = false;
  }

  template <typename Functor>
  ScopeGuard(ScopeGuard<Functor>&& that) : f_(std::move(that.f_)), active_(that.active_) {
    
    
    that.active_ = false;
  }

  ~ScopeGuard() {
    
    
    if (active_) f_();
  }

  private:
  template <typename Functor>
  friend class ScopeGuard;

  F f_;
  bool active_;
};

template <typename F>
ScopeGuard<F> make_scope_guard(F&& f) {
    
    
  return ScopeGuard<F>(std::forward<F>(f));
}

24. stringprintf.h

An auxiliary function for concatenating strings in a format similar to the printf function.
Can be replaced by libfmt.

std::string StringPrintf(const char* fmt, ...);
void StringAppendF(std::string* dst, const char* fmt, ...);
void StringAppendV(std::string* dst, const char* format, va_list ap);

25. strings.h

Auxiliary functions for string operations, part of which can be replaced by standard library functions of std::string.

std::vector<std::string> Split(const std::string& s,
                               const std::string& delimiters);

std::string Trim(const std::string& s);

template <typename ContainerT, typename SeparatorT>
std::string Join(const ContainerT& things, SeparatorT separator);

// We instantiate the common cases in strings.cpp.
extern template std::string Join(const std::vector<std::string>&, char);
extern template std::string Join(const std::vector<const char*>&, char);
extern template std::string Join(const std::vector<std::string>&, const std::string&);
extern template std::string Join(const std::vector<const char*>&, const std::string&);

bool StartsWith(std::string_view s, std::string_view prefix);
bool StartsWith(std::string_view s, char prefix);
bool StartsWithIgnoreCase(std::string_view s, std::string_view prefix);

bool EndsWith(std::string_view s, std::string_view suffix);
bool EndsWith(std::string_view s, char suffix);
bool EndsWithIgnoreCase(std::string_view s, std::string_view suffix);

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

// 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);

// Replaces `from` with `to` in `s`, once if `all == false`, or as many times as
// there are matches if `all == true`.
[[nodiscard]] std::string StringReplace(std::string_view s, std::string_view from,
                                        std::string_view to, bool all);

26. test_utils.h

gtest helper classes and macros.
The assert_ and expect_ macros encapsulate the std::regex_search and gtest macros.

class CapturedStdFd#define ASSERT_MATCH(str, pattern);
#define ASSERT_NOT_MATCH(str, pattern);
#define EXPECT_MATCH(str, pattern);
#define EXPECT_NOT_MATCH(str, pattern);

27. thread_annotations.h

#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))

#define CAPABILITY(x) \
      THREAD_ANNOTATION_ATTRIBUTE__(capability(x))

#define SCOPED_CAPABILITY \
      THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)

#define SHARED_CAPABILITY(...) \
      THREAD_ANNOTATION_ATTRIBUTE__(shared_capability(__VA_ARGS__))

#define GUARDED_BY(x) \
      THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))

#define EXCLUSIVE_LOCKS_REQUIRED(...) \
      THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))

#define SHARED_LOCKS_REQUIRED(...) \
      THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))

#define ACQUIRED_BEFORE(...) \
      THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
...

1) Some thread-related __attribute__ macro definitions.
2) ScopedLockAssertion, an auxiliary class for Clang to do thread safety analysis.

28. threads.h

Cross-platform support to get thread id, call gettid() or syscall(__NR_gettid) on Linux

uint64_t GetThreadId();

29. unique_fd.h

An RAII class that encapsulates fd, providing unique_fd and borrowed_fd.

// 有bug的代码
     int print(int fd) {
    
    
         int rc;
         char buf[128];
         while ((rc = read(fd, buf, sizeof(buf))) > 0) {
    
    
             printf("%.*s", rc);
         }
         close(fd);
     }

     int bug() {
    
    
         FILE* f = fopen("foo", "r");
         print(fileno(f));
         fclose(f); // print中还在使用文件,外面把文件close了
     }
// Container for a file descriptor that automatically closes the descriptor as
// it goes out of scope.
//
      unique_fd ufd(open("/some/path", "r"));
      if (ufd.get() == -1) return error;
      // Do something useful, possibly including 'return'.
      return 0; // Descriptor is closed for you.


inline FILE* Fdopen(unique_fd&& ufd, const char* mode) {
    
    
inline DIR* Fdopendir(unique_fd&& ufd) {
    
    
template <typename T>
int close(const android::base::unique_fd_impl<T>&);
template <typename T>
FILE* fdopen(const android::base::unique_fd_impl<T>&, const char* mode);
template <typename T>
DIR* fdopendir(const android::base::unique_fd_impl<T>&);

30. utf8.h

The function for converting between UTF and wchar on the Windows platform.

Guess you like

Origin blog.csdn.net/yinminsumeng/article/details/131214878