Desarrollo nativo de Android: sistema/núcleo/base

1. crono_utils.h

Multiplataforma, proporcionando diferentes implementaciones para Linux y Win/Darwin.

class boot_clock;
class Timer;

2. cmsg.h

Linux proporciona macros de la serie cmsg(3) para administrar los mensajes de control relacionados con los sockets locales.
El empaquetado de cmsg evita la posibilidad de errores.

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. colecciones.h

Función auxiliar que coloca los parámetros de longitud variable de la plantilla en el contenedor de recolección.

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

Algunas definiciones de macro encapsulan la función __builtin_bswap16/32/64.
Un equivalente multiplataforma de la biblioteca C estándar <sys/endian.h>.

5. errno_restorer.h

Guarde temporalmente errno y restáurelo después de que finalice el alcance.

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

6. errores.h

Soporte multiplataforma para convertir códigos de error en cadenas, llamando a strerror en Linux.

std::string SystemErrorCodeToString(int error_code);

7. esperado.h

Implementa std::esperado.
Cuando std::expected ingresa oficialmente al estándar C++, esta implementación se elimina y android::base::expected solo se usa como un alias de 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. archivo.h

Funciones auxiliares para operaciones con archivos.

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. formato.h

A través de este archivo de encabezado, se puede introducir la biblioteca fmtlib. Esta biblioteca está vinculada estáticamente a libbase.
Los siguientes son algunos ejemplos de uso, que están disponibles en el código nativo de Android.

// 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. registro.h

El registro encapsulado por la interfaz de flujo de C++.
Salidas de Android a logcat y salidas de host a stderr. La salida se puede configurar con SetLogger.
De manera predeterminada, el nombre del proceso se usa como etiqueta y también se puede definir la macro LOG_TAG (antes del archivo de encabezado de inclusión).

También se proporcionan algunas macros de afirmación. COMPROBAR, COMPROBAR_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

Varias definiciones de macro.

#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. archivo_mapeado.h

Proporcione una implementación multiplataforma de mapeo de archivos.

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. memoria.h

2 funciones auxiliares de memcpy.

// 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: No entiendo muy bien ¿cuál es el propósito de esta clase? ?
Inicialice un objeto de tipo T en el espacio de la pila utilizando la ubicación nueva.

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

Analizar cadena en tipo bool (encapsulación ParseBoolResult).

ParseBoolResult ParseBool(std::string_view s);

17. parsedouble.h

Analiza la cadena en tipo doble.
TODO: ¿Son todas funciones estáticas? ¿No se puede llamar externamente?

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

función auxiliar de análisis de cadenas int.

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. parsenetdirección.h

Función auxiliar de dirección de red de análisis de cadenas.

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

20. proceso.h

Recorra el directorio /proc para obtener todos los 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. propiedades.h

Encapsule la interfaz de propiedades de lectura y escritura.

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. resultado.h

1) Result<T>Contiene un valor de tipo T (similar a optional<T>access), o contiene información de error de tipo ResultError (a través de Result<T>::error()access)
2) ResultError contiene un tipo de cadena de información y errno, y se puede generar directamente con ostream.
3) ResultError<void>Para las funciones que no devuelven un valor, la función devuelve con éxito, return { }.
4) El devuelto ResultError<T>puede construir automáticamente ResultError devolviendo un objeto de tipo T, o cualquier objeto que se pueda convertir a tipo T.
5) Error y ErrnoError se utilizan para crear errores Result<T>, y Errorf y ErrnoErrorf dan formato y emiten mensajes de error.
6) El tipo ResultError se puede construir directamente 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. protector de alcance.h

Proporciona una clase auxiliar de RAII que garantiza que se llame a la función (objeto) especificada cuando finalice el ámbito.

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

Una función auxiliar para concatenar cadenas en un formato similar a la función printf.
Puede ser reemplazado por 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. cuerdas.h

Funciones auxiliares para operaciones con cadenas, parte de las cuales pueden ser reemplazadas por funciones de biblioteca estándar de 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

macros y clases auxiliares de gtest.
Las macros assert_ y expect_ encapsulan las macros std::regex_search y gtest.

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. hilo_anotaciones.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) Algunas definiciones de macro __attribute__ relacionadas con subprocesos.
2) ScopedLockAssertion, una clase auxiliar para Clang para realizar análisis de seguridad de subprocesos.

28. hilos.h

Soporte multiplataforma para obtener la identificación del hilo, llame a gettid () o syscall (__NR_gettid) en Linux

uint64_t GetThreadId();

29. único_fd.h

Una clase RAII que encapsula fd, proporcionando un_fd único y un fd prestado.

// 有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

La función para convertir entre UTF y wchar en la plataforma Windows.

Supongo que te gusta

Origin blog.csdn.net/yinminsumeng/article/details/131214878
Recomendado
Clasificación