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