1*897a1d94STom Rini /* SPDX-License-Identifier: MIT */ 2d8f9d2afSIgor Opaniuk /* 3d8f9d2afSIgor Opaniuk * Copyright (C) 2016 The Android Open Source Project 4d8f9d2afSIgor Opaniuk */ 5d8f9d2afSIgor Opaniuk 6d8f9d2afSIgor Opaniuk #if !defined(AVB_INSIDE_LIBAVB_H) && !defined(AVB_COMPILATION) 7d8f9d2afSIgor Opaniuk #error "Never include this file directly, include libavb.h instead." 8d8f9d2afSIgor Opaniuk #endif 9d8f9d2afSIgor Opaniuk 10d8f9d2afSIgor Opaniuk #ifndef AVB_UTIL_H_ 11d8f9d2afSIgor Opaniuk #define AVB_UTIL_H_ 12d8f9d2afSIgor Opaniuk 13d8f9d2afSIgor Opaniuk #include "avb_sysdeps.h" 14d8f9d2afSIgor Opaniuk 15d8f9d2afSIgor Opaniuk #ifdef __cplusplus 16d8f9d2afSIgor Opaniuk extern "C" { 17d8f9d2afSIgor Opaniuk #endif 18d8f9d2afSIgor Opaniuk 19d8f9d2afSIgor Opaniuk #define AVB_STRINGIFY(x) #x 20d8f9d2afSIgor Opaniuk #define AVB_TO_STRING(x) AVB_STRINGIFY(x) 21d8f9d2afSIgor Opaniuk 22d8f9d2afSIgor Opaniuk #ifdef AVB_ENABLE_DEBUG 23d8f9d2afSIgor Opaniuk /* Aborts the program if |expr| is false. 24d8f9d2afSIgor Opaniuk * 25d8f9d2afSIgor Opaniuk * This has no effect unless AVB_ENABLE_DEBUG is defined. 26d8f9d2afSIgor Opaniuk */ 27d8f9d2afSIgor Opaniuk #define avb_assert(expr) \ 28d8f9d2afSIgor Opaniuk do { \ 29d8f9d2afSIgor Opaniuk if (!(expr)) { \ 30d8f9d2afSIgor Opaniuk avb_fatal("assert fail: " #expr "\n"); \ 31d8f9d2afSIgor Opaniuk } \ 32d8f9d2afSIgor Opaniuk } while (0) 33d8f9d2afSIgor Opaniuk #else 34d8f9d2afSIgor Opaniuk #define avb_assert(expr) 35d8f9d2afSIgor Opaniuk #endif 36d8f9d2afSIgor Opaniuk 37d8f9d2afSIgor Opaniuk /* Aborts the program if reached. 38d8f9d2afSIgor Opaniuk * 39d8f9d2afSIgor Opaniuk * This has no effect unless AVB_ENABLE_DEBUG is defined. 40d8f9d2afSIgor Opaniuk */ 41d8f9d2afSIgor Opaniuk #ifdef AVB_ENABLE_DEBUG 42d8f9d2afSIgor Opaniuk #define avb_assert_not_reached() \ 43d8f9d2afSIgor Opaniuk do { \ 44d8f9d2afSIgor Opaniuk avb_fatal("assert_not_reached()\n"); \ 45d8f9d2afSIgor Opaniuk } while (0) 46d8f9d2afSIgor Opaniuk #else 47d8f9d2afSIgor Opaniuk #define avb_assert_not_reached() 48d8f9d2afSIgor Opaniuk #endif 49d8f9d2afSIgor Opaniuk 50d8f9d2afSIgor Opaniuk /* Aborts the program if |addr| is not word-aligned. 51d8f9d2afSIgor Opaniuk * 52d8f9d2afSIgor Opaniuk * This has no effect unless AVB_ENABLE_DEBUG is defined. 53d8f9d2afSIgor Opaniuk */ 54d8f9d2afSIgor Opaniuk #define avb_assert_aligned(addr) \ 55d8f9d2afSIgor Opaniuk avb_assert((((uintptr_t)addr) & (AVB_ALIGNMENT_SIZE - 1)) == 0) 56d8f9d2afSIgor Opaniuk 57d8f9d2afSIgor Opaniuk #ifdef AVB_ENABLE_DEBUG 58d8f9d2afSIgor Opaniuk /* Print functions, used for diagnostics. 59d8f9d2afSIgor Opaniuk * 60d8f9d2afSIgor Opaniuk * These have no effect unless AVB_ENABLE_DEBUG is defined. 61d8f9d2afSIgor Opaniuk */ 62d8f9d2afSIgor Opaniuk #define avb_debug(message) \ 63d8f9d2afSIgor Opaniuk do { \ 64d8f9d2afSIgor Opaniuk avb_printv(avb_basename(__FILE__), \ 65d8f9d2afSIgor Opaniuk ":", \ 66d8f9d2afSIgor Opaniuk AVB_TO_STRING(__LINE__), \ 67d8f9d2afSIgor Opaniuk ": DEBUG: ", \ 68d8f9d2afSIgor Opaniuk message, \ 69d8f9d2afSIgor Opaniuk NULL); \ 70d8f9d2afSIgor Opaniuk } while (0) 71d8f9d2afSIgor Opaniuk #define avb_debugv(message, ...) \ 72d8f9d2afSIgor Opaniuk do { \ 73d8f9d2afSIgor Opaniuk avb_printv(avb_basename(__FILE__), \ 74d8f9d2afSIgor Opaniuk ":", \ 75d8f9d2afSIgor Opaniuk AVB_TO_STRING(__LINE__), \ 76d8f9d2afSIgor Opaniuk ": DEBUG: ", \ 77d8f9d2afSIgor Opaniuk message, \ 78d8f9d2afSIgor Opaniuk ##__VA_ARGS__); \ 79d8f9d2afSIgor Opaniuk } while (0) 80d8f9d2afSIgor Opaniuk #else 81d8f9d2afSIgor Opaniuk #define avb_debug(message) 82d8f9d2afSIgor Opaniuk #define avb_debugv(message, ...) 83d8f9d2afSIgor Opaniuk #endif 84d8f9d2afSIgor Opaniuk 85d8f9d2afSIgor Opaniuk /* Prints out a message. This is typically used if a runtime-error 86d8f9d2afSIgor Opaniuk * occurs. 87d8f9d2afSIgor Opaniuk */ 88d8f9d2afSIgor Opaniuk #define avb_error(message) \ 89d8f9d2afSIgor Opaniuk do { \ 90d8f9d2afSIgor Opaniuk avb_printv(avb_basename(__FILE__), \ 91d8f9d2afSIgor Opaniuk ":", \ 92d8f9d2afSIgor Opaniuk AVB_TO_STRING(__LINE__), \ 93d8f9d2afSIgor Opaniuk ": ERROR: ", \ 94d8f9d2afSIgor Opaniuk message, \ 95d8f9d2afSIgor Opaniuk NULL); \ 96d8f9d2afSIgor Opaniuk } while (0) 97d8f9d2afSIgor Opaniuk #define avb_errorv(message, ...) \ 98d8f9d2afSIgor Opaniuk do { \ 99d8f9d2afSIgor Opaniuk avb_printv(avb_basename(__FILE__), \ 100d8f9d2afSIgor Opaniuk ":", \ 101d8f9d2afSIgor Opaniuk AVB_TO_STRING(__LINE__), \ 102d8f9d2afSIgor Opaniuk ": ERROR: ", \ 103d8f9d2afSIgor Opaniuk message, \ 104d8f9d2afSIgor Opaniuk ##__VA_ARGS__); \ 105d8f9d2afSIgor Opaniuk } while (0) 106d8f9d2afSIgor Opaniuk 107d8f9d2afSIgor Opaniuk /* Prints out a message and calls avb_abort(). 108d8f9d2afSIgor Opaniuk */ 109d8f9d2afSIgor Opaniuk #define avb_fatal(message) \ 110d8f9d2afSIgor Opaniuk do { \ 111d8f9d2afSIgor Opaniuk avb_printv(avb_basename(__FILE__), \ 112d8f9d2afSIgor Opaniuk ":", \ 113d8f9d2afSIgor Opaniuk AVB_TO_STRING(__LINE__), \ 114d8f9d2afSIgor Opaniuk ": FATAL: ", \ 115d8f9d2afSIgor Opaniuk message, \ 116d8f9d2afSIgor Opaniuk NULL); \ 117d8f9d2afSIgor Opaniuk avb_abort(); \ 118d8f9d2afSIgor Opaniuk } while (0) 119d8f9d2afSIgor Opaniuk #define avb_fatalv(message, ...) \ 120d8f9d2afSIgor Opaniuk do { \ 121d8f9d2afSIgor Opaniuk avb_printv(avb_basename(__FILE__), \ 122d8f9d2afSIgor Opaniuk ":", \ 123d8f9d2afSIgor Opaniuk AVB_TO_STRING(__LINE__), \ 124d8f9d2afSIgor Opaniuk ": FATAL: ", \ 125d8f9d2afSIgor Opaniuk message, \ 126d8f9d2afSIgor Opaniuk ##__VA_ARGS__); \ 127d8f9d2afSIgor Opaniuk avb_abort(); \ 128d8f9d2afSIgor Opaniuk } while (0) 129d8f9d2afSIgor Opaniuk 130d8f9d2afSIgor Opaniuk /* Converts a 32-bit unsigned integer from big-endian to host byte order. */ 131d8f9d2afSIgor Opaniuk uint32_t avb_be32toh(uint32_t in) AVB_ATTR_WARN_UNUSED_RESULT; 132d8f9d2afSIgor Opaniuk 133d8f9d2afSIgor Opaniuk /* Converts a 64-bit unsigned integer from big-endian to host byte order. */ 134d8f9d2afSIgor Opaniuk uint64_t avb_be64toh(uint64_t in) AVB_ATTR_WARN_UNUSED_RESULT; 135d8f9d2afSIgor Opaniuk 136d8f9d2afSIgor Opaniuk /* Converts a 32-bit unsigned integer from host to big-endian byte order. */ 137d8f9d2afSIgor Opaniuk uint32_t avb_htobe32(uint32_t in) AVB_ATTR_WARN_UNUSED_RESULT; 138d8f9d2afSIgor Opaniuk 139d8f9d2afSIgor Opaniuk /* Converts a 64-bit unsigned integer from host to big-endian byte order. */ 140d8f9d2afSIgor Opaniuk uint64_t avb_htobe64(uint64_t in) AVB_ATTR_WARN_UNUSED_RESULT; 141d8f9d2afSIgor Opaniuk 142d8f9d2afSIgor Opaniuk /* Compare |n| bytes starting at |s1| with |s2| and return 0 if they 143d8f9d2afSIgor Opaniuk * match, 1 if they don't. Returns 0 if |n|==0, since no bytes 144d8f9d2afSIgor Opaniuk * mismatched. 145d8f9d2afSIgor Opaniuk * 146d8f9d2afSIgor Opaniuk * Time taken to perform the comparison is only dependent on |n| and 147d8f9d2afSIgor Opaniuk * not on the relationship of the match between |s1| and |s2|. 148d8f9d2afSIgor Opaniuk * 149d8f9d2afSIgor Opaniuk * Note that unlike avb_memcmp(), this only indicates inequality, not 150d8f9d2afSIgor Opaniuk * whether |s1| is less than or greater than |s2|. 151d8f9d2afSIgor Opaniuk */ 152d8f9d2afSIgor Opaniuk int avb_safe_memcmp(const void* s1, 153d8f9d2afSIgor Opaniuk const void* s2, 154d8f9d2afSIgor Opaniuk size_t n) AVB_ATTR_WARN_UNUSED_RESULT; 155d8f9d2afSIgor Opaniuk 156d8f9d2afSIgor Opaniuk /* Adds |value_to_add| to |value| with overflow protection. 157d8f9d2afSIgor Opaniuk * 158d8f9d2afSIgor Opaniuk * Returns false if the addition overflows, true otherwise. In either 159d8f9d2afSIgor Opaniuk * case, |value| is always modified. 160d8f9d2afSIgor Opaniuk */ 161d8f9d2afSIgor Opaniuk bool avb_safe_add_to(uint64_t* value, 162d8f9d2afSIgor Opaniuk uint64_t value_to_add) AVB_ATTR_WARN_UNUSED_RESULT; 163d8f9d2afSIgor Opaniuk 164d8f9d2afSIgor Opaniuk /* Adds |a| and |b| with overflow protection, returning the value in 165d8f9d2afSIgor Opaniuk * |out_result|. 166d8f9d2afSIgor Opaniuk * 167d8f9d2afSIgor Opaniuk * It's permissible to pass NULL for |out_result| if you just want to 168d8f9d2afSIgor Opaniuk * check that the addition would not overflow. 169d8f9d2afSIgor Opaniuk * 170d8f9d2afSIgor Opaniuk * Returns false if the addition overflows, true otherwise. 171d8f9d2afSIgor Opaniuk */ 172d8f9d2afSIgor Opaniuk bool avb_safe_add(uint64_t* out_result, 173d8f9d2afSIgor Opaniuk uint64_t a, 174d8f9d2afSIgor Opaniuk uint64_t b) AVB_ATTR_WARN_UNUSED_RESULT; 175d8f9d2afSIgor Opaniuk 176d8f9d2afSIgor Opaniuk /* Checks if |num_bytes| data at |data| is a valid UTF-8 177d8f9d2afSIgor Opaniuk * string. Returns true if valid UTF-8, false otherwise. 178d8f9d2afSIgor Opaniuk */ 179d8f9d2afSIgor Opaniuk bool avb_validate_utf8(const uint8_t* data, 180d8f9d2afSIgor Opaniuk size_t num_bytes) AVB_ATTR_WARN_UNUSED_RESULT; 181d8f9d2afSIgor Opaniuk 182d8f9d2afSIgor Opaniuk /* Concatenates |str1| (of |str1_len| bytes) and |str2| (of |str2_len| 183d8f9d2afSIgor Opaniuk * bytes) and puts the result in |buf| which holds |buf_size| 184d8f9d2afSIgor Opaniuk * bytes. The result is also guaranteed to be NUL terminated. Fail if 185d8f9d2afSIgor Opaniuk * there is not enough room in |buf| for the resulting string plus 186d8f9d2afSIgor Opaniuk * terminating NUL byte. 187d8f9d2afSIgor Opaniuk * 188d8f9d2afSIgor Opaniuk * Returns true if the operation succeeds, false otherwise. 189d8f9d2afSIgor Opaniuk */ 190d8f9d2afSIgor Opaniuk bool avb_str_concat(char* buf, 191d8f9d2afSIgor Opaniuk size_t buf_size, 192d8f9d2afSIgor Opaniuk const char* str1, 193d8f9d2afSIgor Opaniuk size_t str1_len, 194d8f9d2afSIgor Opaniuk const char* str2, 195d8f9d2afSIgor Opaniuk size_t str2_len); 196d8f9d2afSIgor Opaniuk 197d8f9d2afSIgor Opaniuk /* Like avb_malloc_() but prints a error using avb_error() if memory 198d8f9d2afSIgor Opaniuk * allocation fails. 199d8f9d2afSIgor Opaniuk */ 200d8f9d2afSIgor Opaniuk void* avb_malloc(size_t size) AVB_ATTR_WARN_UNUSED_RESULT; 201d8f9d2afSIgor Opaniuk 202d8f9d2afSIgor Opaniuk /* Like avb_malloc() but sets the memory with zeroes. */ 203d8f9d2afSIgor Opaniuk void* avb_calloc(size_t size) AVB_ATTR_WARN_UNUSED_RESULT; 204d8f9d2afSIgor Opaniuk 205d8f9d2afSIgor Opaniuk /* Duplicates a NUL-terminated string. Returns NULL on OOM. */ 206d8f9d2afSIgor Opaniuk char* avb_strdup(const char* str) AVB_ATTR_WARN_UNUSED_RESULT; 207d8f9d2afSIgor Opaniuk 208d8f9d2afSIgor Opaniuk /* Duplicates a NULL-terminated array of NUL-terminated strings by 209d8f9d2afSIgor Opaniuk * concatenating them. The returned string will be 210d8f9d2afSIgor Opaniuk * NUL-terminated. Returns NULL on OOM. 211d8f9d2afSIgor Opaniuk */ 212d8f9d2afSIgor Opaniuk char* avb_strdupv(const char* str, 213d8f9d2afSIgor Opaniuk ...) AVB_ATTR_WARN_UNUSED_RESULT AVB_ATTR_SENTINEL; 214d8f9d2afSIgor Opaniuk 215d8f9d2afSIgor Opaniuk /* Finds the first occurrence of |needle| in the string |haystack| 216d8f9d2afSIgor Opaniuk * where both strings are NUL-terminated strings. The terminating NUL 217d8f9d2afSIgor Opaniuk * bytes are not compared. 218d8f9d2afSIgor Opaniuk * 219d8f9d2afSIgor Opaniuk * Returns NULL if not found, otherwise points into |haystack| for the 220d8f9d2afSIgor Opaniuk * first occurrence of |needle|. 221d8f9d2afSIgor Opaniuk */ 222d8f9d2afSIgor Opaniuk const char* avb_strstr(const char* haystack, 223d8f9d2afSIgor Opaniuk const char* needle) AVB_ATTR_WARN_UNUSED_RESULT; 224d8f9d2afSIgor Opaniuk 225d8f9d2afSIgor Opaniuk /* Finds the first occurrence of |str| in the NULL-terminated string 226d8f9d2afSIgor Opaniuk * array |strings|. Each element in |strings| must be 227d8f9d2afSIgor Opaniuk * NUL-terminated. The string given by |str| need not be 228d8f9d2afSIgor Opaniuk * NUL-terminated but its size must be given in |str_size|. 229d8f9d2afSIgor Opaniuk * 230d8f9d2afSIgor Opaniuk * Returns NULL if not found, otherwise points into |strings| for the 231d8f9d2afSIgor Opaniuk * first occurrence of |str|. 232d8f9d2afSIgor Opaniuk */ 233d8f9d2afSIgor Opaniuk const char* avb_strv_find_str(const char* const* strings, 234d8f9d2afSIgor Opaniuk const char* str, 235d8f9d2afSIgor Opaniuk size_t str_size); 236d8f9d2afSIgor Opaniuk 237d8f9d2afSIgor Opaniuk /* Replaces all occurrences of |search| with |replace| in |str|. 238d8f9d2afSIgor Opaniuk * 239d8f9d2afSIgor Opaniuk * Returns a newly allocated string or NULL if out of memory. 240d8f9d2afSIgor Opaniuk */ 241d8f9d2afSIgor Opaniuk char* avb_replace(const char* str, 242d8f9d2afSIgor Opaniuk const char* search, 243d8f9d2afSIgor Opaniuk const char* replace) AVB_ATTR_WARN_UNUSED_RESULT; 244d8f9d2afSIgor Opaniuk 245d8f9d2afSIgor Opaniuk /* Calculates the CRC-32 for data in |buf| of size |buf_size|. */ 246d8f9d2afSIgor Opaniuk uint32_t avb_crc32(const uint8_t* buf, size_t buf_size); 247d8f9d2afSIgor Opaniuk 248d8f9d2afSIgor Opaniuk /* Returns the basename of |str|. This is defined as the last path 249d8f9d2afSIgor Opaniuk * component, assuming the normal POSIX separator '/'. If there are no 250d8f9d2afSIgor Opaniuk * separators, returns |str|. 251d8f9d2afSIgor Opaniuk */ 252d8f9d2afSIgor Opaniuk const char* avb_basename(const char* str); 253d8f9d2afSIgor Opaniuk 254d8f9d2afSIgor Opaniuk /* Converts any ascii lowercase characters in |str| to uppercase in-place. 255d8f9d2afSIgor Opaniuk * |str| must be NUL-terminated and valid UTF-8. 256d8f9d2afSIgor Opaniuk */ 257d8f9d2afSIgor Opaniuk void avb_uppercase(char* str); 258d8f9d2afSIgor Opaniuk 259d8f9d2afSIgor Opaniuk /* Converts |data_len| bytes of |data| to hex and returns the result. Returns 260d8f9d2afSIgor Opaniuk * NULL on OOM. Caller must free the returned string with avb_free. 261d8f9d2afSIgor Opaniuk */ 262d8f9d2afSIgor Opaniuk char* avb_bin2hex(const uint8_t* data, size_t data_len); 263d8f9d2afSIgor Opaniuk 264d8f9d2afSIgor Opaniuk #ifdef __cplusplus 265d8f9d2afSIgor Opaniuk } 266d8f9d2afSIgor Opaniuk #endif 267d8f9d2afSIgor Opaniuk 268d8f9d2afSIgor Opaniuk #endif /* AVB_UTIL_H_ */ 269