121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen/* 221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen * Copyright (C) 2016 The Android Open Source Project 321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen * 4c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * Permission is hereby granted, free of charge, to any person 5c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * obtaining a copy of this software and associated documentation 6c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * files (the "Software"), to deal in the Software without 7c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * restriction, including without limitation the rights to use, copy, 8c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * modify, merge, publish, distribute, sublicense, and/or sell copies 9c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * of the Software, and to permit persons to whom the Software is 10c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * furnished to do so, subject to the following conditions: 1121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen * 12c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * The above copyright notice and this permission notice shall be 13c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * included in all copies or substantial portions of the Software. 1421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen * 15c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * SOFTWARE. 2321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen */ 2421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 2521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen#include "avb_util.h" 2621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 2719c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen#include <stdarg.h> 2819c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen 2921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenuint32_t avb_be32toh(uint32_t in) { 3021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen uint8_t* d = (uint8_t*)∈ 3121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen uint32_t ret; 3221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret = ((uint32_t)d[0]) << 24; 3321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret |= ((uint32_t)d[1]) << 16; 3421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret |= ((uint32_t)d[2]) << 8; 3521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret |= ((uint32_t)d[3]); 3621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return ret; 3721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen} 3821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 3921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenuint64_t avb_be64toh(uint64_t in) { 4021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen uint8_t* d = (uint8_t*)∈ 4121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen uint64_t ret; 4221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret = ((uint64_t)d[0]) << 56; 4321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret |= ((uint64_t)d[1]) << 48; 4421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret |= ((uint64_t)d[2]) << 40; 4521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret |= ((uint64_t)d[3]) << 32; 4621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret |= ((uint64_t)d[4]) << 24; 4721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret |= ((uint64_t)d[5]) << 16; 4821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret |= ((uint64_t)d[6]) << 8; 4921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret |= ((uint64_t)d[7]); 5021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return ret; 5121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen} 5221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 538b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen/* Converts a 32-bit unsigned integer from host to big-endian byte order. */ 548b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthenuint32_t avb_htobe32(uint32_t in) { 558b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen union { 568b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen uint32_t word; 578b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen uint8_t bytes[4]; 588b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen } ret; 598b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen ret.bytes[0] = (in >> 24) & 0xff; 608b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen ret.bytes[1] = (in >> 16) & 0xff; 618b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen ret.bytes[2] = (in >> 8) & 0xff; 628b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen ret.bytes[3] = in & 0xff; 638b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen return ret.word; 648b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen} 658b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen 668b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen/* Converts a 64-bit unsigned integer from host to big-endian byte order. */ 678b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthenuint64_t avb_htobe64(uint64_t in) { 688b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen union { 698b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen uint64_t word; 708b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen uint8_t bytes[8]; 718b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen } ret; 728b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen ret.bytes[0] = (in >> 56) & 0xff; 738b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen ret.bytes[1] = (in >> 48) & 0xff; 748b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen ret.bytes[2] = (in >> 40) & 0xff; 758b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen ret.bytes[3] = (in >> 32) & 0xff; 768b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen ret.bytes[4] = (in >> 24) & 0xff; 778b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen ret.bytes[5] = (in >> 16) & 0xff; 788b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen ret.bytes[6] = (in >> 8) & 0xff; 798b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen ret.bytes[7] = in & 0xff; 808b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen return ret.word; 818b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen} 828b6973be7468f5c0db42ff8fcd91f8e97a345a27David Zeuthen 8321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenint avb_safe_memcmp(const void* s1, const void* s2, size_t n) { 8421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen const unsigned char* us1 = s1; 8521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen const unsigned char* us2 = s2; 8621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen int result = 0; 8721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 884b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen if (0 == n) { 894b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen return 0; 904b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen } 9121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 9221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* 9321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen * Code snippet without data-dependent branch due to Nate Lawson 9421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen * (nate@root.org) of Root Labs. 9521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen */ 964b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen while (n--) { 974b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen result |= *us1++ ^ *us2++; 984b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen } 9921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 10021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return result != 0; 10121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen} 10221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 10321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenbool avb_safe_add_to(uint64_t* value, uint64_t value_to_add) { 10421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen uint64_t original_value; 10521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 10621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_assert(value != NULL); 10721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 10821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen original_value = *value; 10921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 11021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen *value += value_to_add; 11121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (*value < original_value) { 11221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Overflow when adding values.\n"); 11321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return false; 11421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 11521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 11621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return true; 11721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen} 11821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 11921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenbool avb_safe_add(uint64_t* out_result, uint64_t a, uint64_t b) { 12021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen uint64_t dummy; 1214b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen if (out_result == NULL) { 1224b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen out_result = &dummy; 1234b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen } 12421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen *out_result = a; 12521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return avb_safe_add_to(out_result, b); 12621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen} 12721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 12821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenbool avb_validate_utf8(const uint8_t* data, size_t num_bytes) { 12921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen size_t n; 13021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen unsigned int num_cc; 13121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 13221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen for (n = 0, num_cc = 0; n < num_bytes; n++) { 13321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen uint8_t c = data[n]; 13421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 13521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (num_cc > 0) { 13621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if ((c & (0x80 | 0x40)) == 0x80) { 13721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* 10xx xxxx */ 13821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } else { 13921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto fail; 14021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 14121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen num_cc--; 14221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } else { 14321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (c < 0x80) { 14421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen num_cc = 0; 14521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } else if ((c & (0x80 | 0x40 | 0x20)) == (0x80 | 0x40)) { 14621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* 110x xxxx */ 14721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen num_cc = 1; 14821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } else if ((c & (0x80 | 0x40 | 0x20 | 0x10)) == (0x80 | 0x40 | 0x20)) { 14921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* 1110 xxxx */ 15021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen num_cc = 2; 15121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } else if ((c & (0x80 | 0x40 | 0x20 | 0x10 | 0x08)) == 15221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen (0x80 | 0x40 | 0x20 | 0x10)) { 15321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* 1111 0xxx */ 15421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen num_cc = 3; 15521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } else { 15621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto fail; 15721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 15821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 15921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 16021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 16121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (num_cc != 0) { 16221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto fail; 16321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 16421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 16521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return true; 16621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 16721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenfail: 16821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return false; 16921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen} 17021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 1714b6a634e48353da1e119ebe0287299f7b919d778David Zeuthenbool avb_str_concat(char* buf, 1724b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen size_t buf_size, 1734b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen const char* str1, 1744b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen size_t str1_len, 1754b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen const char* str2, 1764b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen size_t str2_len) { 17721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen uint64_t combined_len; 17821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 17921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (!avb_safe_add(&combined_len, str1_len, str2_len)) { 18021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Overflow when adding string sizes.\n"); 18121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return false; 18221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 18321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 18421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (combined_len > buf_size - 1) { 18521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Insufficient buffer space.\n"); 18621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return false; 18721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 18821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 18921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_memcpy(buf, str1, str1_len); 19021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_memcpy(buf + str1_len, str2, str2_len); 19121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen buf[combined_len] = '\0'; 19221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 19321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return true; 19421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen} 19521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 19621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenvoid* avb_malloc(size_t size) { 19721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen void* ret = avb_malloc_(size); 19821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (ret == NULL) { 19921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Failed to allocate memory.\n"); 20021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return NULL; 20121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 20221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return ret; 20321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen} 20421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 20521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenvoid* avb_calloc(size_t size) { 20621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen void* ret = avb_malloc(size); 20721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (ret == NULL) { 20821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return NULL; 20921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 21021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 21121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_memset(ret, '\0', size); 21221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return ret; 21321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen} 21421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 21521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenchar* avb_strdup(const char* str) { 21621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen size_t len = avb_strlen(str); 21721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen char* ret = avb_malloc(len + 1); 21821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (ret == NULL) { 21921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return NULL; 22021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 22121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 22221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_memcpy(ret, str, len); 22321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret[len] = '\0'; 22421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 22521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return ret; 22621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen} 22721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 22821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenconst char* avb_strstr(const char* haystack, const char* needle) { 22921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen size_t n, m; 23021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 23121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* Look through |haystack| and check if the first character of 23221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen * |needle| matches. If so, check the rest of |needle|. 23321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen */ 23421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen for (n = 0; haystack[n] != '\0'; n++) { 2354b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen if (haystack[n] != needle[0]) { 2364b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen continue; 2374b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen } 23821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 23921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen for (m = 1;; m++) { 24021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (needle[m] == '\0') { 24121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return haystack + n; 24221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 24321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 2444b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen if (haystack[n + m] != needle[m]) { 2454b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen break; 2464b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen } 24721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 24821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 24921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 25021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return NULL; 25121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen} 25221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 2534b6a634e48353da1e119ebe0287299f7b919d778David Zeuthenconst char* avb_strv_find_str(const char* const* strings, 2544b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen const char* str, 255a8bb9a0e8635e3562367ebfe89b1870b4e2cc8e2David Zeuthen size_t str_size) { 256a8bb9a0e8635e3562367ebfe89b1870b4e2cc8e2David Zeuthen size_t n; 257a8bb9a0e8635e3562367ebfe89b1870b4e2cc8e2David Zeuthen for (n = 0; strings[n] != NULL; n++) { 258a8bb9a0e8635e3562367ebfe89b1870b4e2cc8e2David Zeuthen if (avb_strlen(strings[n]) == str_size && 259a8bb9a0e8635e3562367ebfe89b1870b4e2cc8e2David Zeuthen avb_memcmp(strings[n], str, str_size) == 0) { 260a8bb9a0e8635e3562367ebfe89b1870b4e2cc8e2David Zeuthen return strings[n]; 261a8bb9a0e8635e3562367ebfe89b1870b4e2cc8e2David Zeuthen } 262a8bb9a0e8635e3562367ebfe89b1870b4e2cc8e2David Zeuthen } 263a8bb9a0e8635e3562367ebfe89b1870b4e2cc8e2David Zeuthen return NULL; 264a8bb9a0e8635e3562367ebfe89b1870b4e2cc8e2David Zeuthen} 265a8bb9a0e8635e3562367ebfe89b1870b4e2cc8e2David Zeuthen 26621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenchar* avb_replace(const char* str, const char* search, const char* replace) { 26721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen char* ret = NULL; 26821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen size_t ret_len = 0; 26921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen size_t search_len, replace_len; 27021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen const char* str_after_last_replace; 27121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 27221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen search_len = avb_strlen(search); 27321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen replace_len = avb_strlen(replace); 27421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 27521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen str_after_last_replace = str; 27621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen while (*str != '\0') { 27721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen const char* s; 27821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen size_t num_before; 27921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen size_t num_new; 28021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 28121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen s = avb_strstr(str, search); 2824b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen if (s == NULL) { 2834b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen break; 2844b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen } 28521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 28621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen num_before = s - str; 28721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 28821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (ret == NULL) { 28921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen num_new = num_before + replace_len + 1; 29021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret = avb_malloc(num_new); 29121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (ret == NULL) { 29221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 29321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 29421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_memcpy(ret, str, num_before); 29521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_memcpy(ret + num_before, replace, replace_len); 29621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret[num_new - 1] = '\0'; 29721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret_len = num_new - 1; 29821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } else { 29921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen char* new_str; 30021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen num_new = ret_len + num_before + replace_len + 1; 30121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen new_str = avb_malloc(num_new); 30221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (ret == NULL) { 30321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 30421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 30521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_memcpy(new_str, ret, ret_len); 30621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_memcpy(new_str + ret_len, str, num_before); 30721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_memcpy(new_str + ret_len + num_before, replace, replace_len); 30821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen new_str[num_new - 1] = '\0'; 30921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_free(ret); 31021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret = new_str; 31121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret_len = num_new - 1; 31221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 31321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 31421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen str = s + search_len; 31521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen str_after_last_replace = str; 31621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 31721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 31821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (ret == NULL) { 31921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret = avb_strdup(str_after_last_replace); 32021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (ret == NULL) { 32121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 32221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 32321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } else { 32421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen size_t num_remaining = avb_strlen(str_after_last_replace); 32521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen size_t num_new = ret_len + num_remaining + 1; 32621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen char* new_str = avb_malloc(num_new); 3274b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen if (ret == NULL) { 3284b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen goto out; 3294b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen } 33021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_memcpy(new_str, ret, ret_len); 33121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_memcpy(new_str + ret_len, str_after_last_replace, num_remaining); 33221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen new_str[num_new - 1] = '\0'; 33321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_free(ret); 33421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret = new_str; 33521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret_len = num_new - 1; 33621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 33721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 33821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenout: 33921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return ret; 34021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen} 34119c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen 34219c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen/* We only support a limited amount of strings in avb_strdupv(). */ 343bc41cead048a90f63e3dd4335097c5588ec09345David Zeuthen#define AVB_STRDUPV_MAX_NUM_STRINGS 32 34419c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen 34519c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthenchar* avb_strdupv(const char* str, ...) { 34619c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen va_list ap; 347bc41cead048a90f63e3dd4335097c5588ec09345David Zeuthen const char* strings[AVB_STRDUPV_MAX_NUM_STRINGS]; 348bc41cead048a90f63e3dd4335097c5588ec09345David Zeuthen size_t lengths[AVB_STRDUPV_MAX_NUM_STRINGS]; 349bc41cead048a90f63e3dd4335097c5588ec09345David Zeuthen size_t num_strings, n; 350bc41cead048a90f63e3dd4335097c5588ec09345David Zeuthen uint64_t total_length; 35119c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen char *ret = NULL, *dest; 35219c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen 35319c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen num_strings = 0; 35419c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen total_length = 0; 35519c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen va_start(ap, str); 35619c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen do { 357bc41cead048a90f63e3dd4335097c5588ec09345David Zeuthen size_t str_len = avb_strlen(str); 35819c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen strings[num_strings] = str; 359bc41cead048a90f63e3dd4335097c5588ec09345David Zeuthen lengths[num_strings] = str_len; 360bc41cead048a90f63e3dd4335097c5588ec09345David Zeuthen if (!avb_safe_add_to(&total_length, str_len)) { 361bc41cead048a90f63e3dd4335097c5588ec09345David Zeuthen avb_fatal("Overflow while determining total length.\n"); 362bc41cead048a90f63e3dd4335097c5588ec09345David Zeuthen break; 363bc41cead048a90f63e3dd4335097c5588ec09345David Zeuthen } 36419c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen num_strings++; 365bc41cead048a90f63e3dd4335097c5588ec09345David Zeuthen if (num_strings == AVB_STRDUPV_MAX_NUM_STRINGS) { 366bc41cead048a90f63e3dd4335097c5588ec09345David Zeuthen avb_fatal("Too many strings passed.\n"); 36719c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen break; 36819c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen } 36919c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen str = va_arg(ap, const char*); 37019c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen } while (str != NULL); 37119c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen va_end(ap); 37219c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen 37319c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen ret = avb_malloc(total_length + 1); 37419c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen if (ret == NULL) { 37519c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen goto out; 37619c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen } 37719c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen 37819c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen dest = ret; 37919c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen for (n = 0; n < num_strings; n++) { 38019c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen avb_memcpy(dest, strings[n], lengths[n]); 38119c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen dest += lengths[n]; 38219c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen } 38319c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen *dest = '\0'; 38419c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen avb_assert(dest == ret + total_length); 38519c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen 38619c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthenout: 38719c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen return ret; 38819c38437eb77101ac30b29135cca58fbc684eaceDavid Zeuthen} 389f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthen 390f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthenconst char* avb_basename(const char* str) { 391f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthen int64_t n; 392f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthen size_t len; 393f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthen 394f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthen len = avb_strlen(str); 395f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthen if (len >= 2) { 396f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthen for (n = len - 2; n >= 0; n--) { 397f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthen if (str[n] == '/') { 398f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthen return str + n + 1; 399f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthen } 400f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthen } 401f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthen } 402f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthen return str; 403f1bdec37f0f97c0640667178b2ac152c54442dfcDavid Zeuthen} 404