util.c (2558B)
1 2 #include "util.h" 3 #include <errno.h> 4 #include <assert.h> 5 6 static bool char_to_hex(unsigned char *val, char c) 7 { 8 if (c >= '0' && c <= '9') { 9 *val = c - '0'; 10 return true; 11 } 12 if (c >= 'a' && c <= 'f') { 13 *val = c - 'a' + 10; 14 return true; 15 } 16 if (c >= 'A' && c <= 'F') { 17 *val = c - 'A' + 10; 18 return true; 19 } 20 return false; 21 } 22 23 bool hex_decode(const char *str, size_t *slen, void *buf, size_t bufsize) 24 { 25 unsigned char v1, v2; 26 unsigned char *p = buf; 27 int len = 0; 28 29 while (*slen > 1) { 30 if (!bufsize || !char_to_hex(&v1, str[0]) || !char_to_hex(&v2, str[1])) { 31 *slen = len; 32 return false; 33 } 34 *(p++) = (v1 << 4) | v2; 35 str += 2; 36 *slen -= 2; 37 bufsize--; 38 len += 2; 39 } 40 *slen = len; 41 return *slen == 0 && bufsize == 0; 42 } 43 44 45 int read_fd(FILE *fd, unsigned char *buf, size_t buflen, size_t *written) 46 { 47 unsigned char *p = buf; 48 int len = 0; 49 *written = 0; 50 51 do { 52 len = fread(p, 1, 4096, fd); 53 *written += len; 54 p += len; 55 if (p > buf + buflen) 56 return 0; 57 } while (len == 4096); 58 59 return 1; 60 } 61 62 63 64 // if typedef doesn't exist (msvc, blah) 65 ssize_t getline(char **lineptr, size_t *n, FILE *stream) { 66 size_t pos; 67 int c; 68 69 if (lineptr == NULL || stream == NULL || n == NULL) { 70 errno = EINVAL; 71 return -1; 72 } 73 74 c = getc(stream); 75 if (c == EOF) { 76 return -1; 77 } 78 79 if (*lineptr == NULL) { 80 *lineptr = malloc(128); 81 if (*lineptr == NULL) { 82 return -1; 83 } 84 *n = 128; 85 } 86 87 pos = 0; 88 while(c != EOF) { 89 if (pos + 1 >= *n) { 90 size_t new_size = *n + (*n >> 2); 91 if (new_size < 128) { 92 new_size = 128; 93 } 94 char *new_ptr = realloc(*lineptr, new_size); 95 if (new_ptr == NULL) { 96 return -1; 97 } 98 *n = new_size; 99 *lineptr = new_ptr; 100 } 101 102 ((unsigned char *)(*lineptr))[pos ++] = c; 103 if (c == '\n') { 104 break; 105 } 106 c = getc(stream); 107 } 108 109 (*lineptr)[pos] = '\0'; 110 return pos; 111 } 112 113 int read_arg_or_stdin(const char *arg, unsigned char *buf, size_t buflen, 114 size_t *written) 115 { 116 if (arg != NULL) { 117 unsigned char *p = buf; 118 bool done = false; 119 for (size_t i = 0; i < buflen; i++) { 120 *p = arg[i]; 121 if (*p == 0 ) { 122 done = true; 123 break; 124 } 125 p++; 126 } 127 128 *written = p - buf; 129 130 return done; 131 } 132 else { 133 int ok = read_fd(stdin, buf, buflen, written); 134 if (!ok) 135 return ok; 136 if (*written == 0) 137 return 0; 138 (*written)--; 139 buf[*written] = 0; 140 return ok; 141 } 142 } 143