Line data Source code
1 : /* SPDX-License-Identifier: BSD-3-Clause 2 : * Copyright (C) 2022 Intel Corporation. 3 : * All rights reserved. 4 : */ 5 : 6 : #include "spdk/hexlify.h" 7 : #include "spdk/log.h" 8 : 9 : static inline int 10 176 : __c2v(char c) 11 : { 12 176 : if ((c >= '0') && (c <= '9')) { 13 110 : return c - '0'; 14 : } 15 66 : if ((c >= 'a') && (c <= 'f')) { 16 48 : return c - 'a' + 10; 17 : } 18 18 : if ((c >= 'A') && (c <= 'F')) { 19 18 : return c - 'A' + 10; 20 : } 21 0 : return -1; 22 176 : } 23 : 24 : static inline signed char 25 0 : __v2c(int c) 26 : { 27 0 : const char hexchar[] = "0123456789abcdef"; 28 0 : if (c < 0 || c > 15) { 29 0 : return -1; 30 : } 31 0 : return hexchar[c]; 32 0 : } 33 : 34 : char * 35 0 : spdk_hexlify(const char *bin, size_t len) 36 : { 37 : char *hex, *phex; 38 : 39 0 : hex = malloc((len * 2) + 1); 40 0 : if (hex == NULL) { 41 0 : return NULL; 42 : } 43 0 : phex = hex; 44 0 : for (size_t i = 0; i < len; i++) { 45 0 : signed char c0 = __v2c((bin[i] >> 4) & 0x0f); 46 0 : signed char c1 = __v2c((bin[i]) & 0x0f); 47 0 : if (c0 < 0 || c1 < 0) { 48 0 : assert(false); 49 : free(hex); 50 : return NULL; 51 : } 52 0 : *phex++ = c0; 53 0 : *phex++ = c1; 54 0 : } 55 0 : *phex = '\0'; 56 0 : return hex; 57 0 : } 58 : 59 : char * 60 7 : spdk_unhexlify(const char *hex) 61 : { 62 : char *res, *pres; 63 7 : size_t len = strlen(hex); 64 : 65 7 : if (len % 2 != 0) { 66 0 : SPDK_ERRLOG("Invalid hex string len %d. It must be mod of 2.\n", (int)len); 67 0 : return NULL; 68 : } 69 7 : res = malloc(len / 2); 70 7 : if (res == NULL) { 71 0 : return NULL; 72 : } 73 7 : pres = res; 74 95 : for (size_t i = 0; i < len; i += 2) { 75 88 : int v0 = __c2v(hex[i]); 76 88 : int v1 = __c2v(hex[i + 1]); 77 88 : if (v0 < 0 || v1 < 0) { 78 0 : SPDK_ERRLOG("Invalid hex string \"%s\"\n", hex); 79 0 : free(res); 80 0 : return NULL; 81 : } 82 88 : *pres++ = (v0 << 4) + v1; 83 88 : } 84 7 : return res; 85 7 : }