| /* Copyright (c) 2015 Google Inc |
| * Davide Libenzi <dlibenzi@google.com> |
| * See LICENSE for details. |
| */ |
| |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <stdint.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| #include <fcntl.h> |
| #include <errno.h> |
| #include "xlib.h" |
| |
| int xopen(const char *path, int flags, mode_t mode) |
| { |
| int fd = open(path, flags, mode); |
| |
| if (fd < 0) { |
| perror(path); |
| exit(1); |
| } |
| |
| return fd; |
| } |
| |
| void xwrite(int fd, const void *data, size_t size) |
| { |
| ssize_t wcount = write(fd, data, size); |
| |
| if (size != (size_t) wcount) { |
| perror("Writing file"); |
| exit(1); |
| } |
| } |
| |
| void xread(int fd, void *data, size_t size) |
| { |
| ssize_t rcount = read(fd, data, size); |
| |
| if (size != (size_t) rcount) { |
| perror("Reading file"); |
| exit(1); |
| } |
| } |
| |
| void xpwrite(int fd, const void *data, size_t size, off_t off) |
| { |
| ssize_t wcount = pwrite(fd, data, size, off); |
| |
| if (size != (size_t) wcount) { |
| perror("Writing file"); |
| exit(1); |
| } |
| } |
| |
| void xpread(int fd, void *data, size_t size, off_t off) |
| { |
| ssize_t rcount = pread(fd, data, size, off); |
| |
| if (size != (size_t) rcount) { |
| perror("Reading file"); |
| exit(1); |
| } |
| } |
| |
| FILE *xfopen(const char *path, const char *mode) |
| { |
| FILE *file = fopen(path, mode); |
| |
| if (!file) { |
| fprintf(stderr, "Unable to open file '%s' for mode '%s': %s\n", |
| path, mode, strerror(errno)); |
| exit(1); |
| } |
| |
| return file; |
| } |
| |
| FILE *xfdopen(int fd, const char *mode) |
| { |
| FILE *file = fdopen(fd, mode); |
| |
| if (!file) { |
| fprintf(stderr, |
| "Unable to reopen fd '%d' for mode '%s': %s\n", fd, |
| mode, strerror(errno)); |
| exit(1); |
| } |
| |
| return file; |
| } |
| |
| off_t xfsize(FILE *file) |
| { |
| struct stat stat_buf; |
| int fd = fileno(file); |
| |
| if (fd < 0) { |
| perror("xfsize fileno"); |
| exit(1); |
| } |
| if (fstat(fd, &stat_buf)) { |
| perror("xfsize fstat"); |
| exit(1); |
| } |
| return stat_buf.st_size; |
| } |
| |
| void xfwrite(const void *data, size_t size, FILE *file) |
| { |
| if (fwrite(data, 1, size, file) != size) { |
| fprintf(stderr, "Unable to write %lu bytes: %s\n", size, |
| strerror(errno)); |
| exit(1); |
| } |
| } |
| |
| void xfseek(FILE *file, off_t offset, int whence) |
| { |
| if (fseeko(file, offset, whence)) { |
| int error = errno; |
| |
| fprintf(stderr, |
| "Unable to seek at offset %ld from %s (fpos=%ld): %s\n", |
| offset, whence == SEEK_SET ? "beginning of file" : |
| (whence == SEEK_END ? "end of file" : |
| "current position"), |
| ftell(file), strerror(error)); |
| exit(1); |
| } |
| } |
| |
| void *xmalloc(size_t size) |
| { |
| void *data = malloc(size); |
| |
| if (!data) { |
| perror("Allocating memory block"); |
| exit(1); |
| } |
| |
| return data; |
| } |
| |
| void *xzmalloc(size_t size) |
| { |
| void *data = xmalloc(size); |
| |
| memset(data, 0, size); |
| |
| return data; |
| } |
| |
| char *xstrdup(const char *str) |
| { |
| char *dstr = strdup(str); |
| |
| if (dstr == NULL) { |
| perror("Duplicating a string"); |
| exit(1); |
| } |
| |
| return dstr; |
| } |
| |
| const char *vb_decode_uint64(const char *data, uint64_t *pval) |
| { |
| unsigned int i; |
| uint64_t val = 0; |
| |
| for (i = 0; (*data & 0x80) != 0; i += 7, data++) |
| val |= (((uint64_t) *data) & 0x7f) << i; |
| *pval = val | ((uint64_t) *data) << i; |
| |
| return data + 1; |
| } |
| |
| int vb_fdecode_uint64(FILE *file, uint64_t *pval) |
| { |
| unsigned int i = 0; |
| uint64_t val = 0; |
| |
| for (;;) { |
| int c = fgetc(file); |
| |
| if (c == EOF) |
| return EOF; |
| val |= (((uint64_t) c) & 0x7f) << i; |
| i += 7; |
| if ((c & 0x80) == 0) |
| break; |
| } |
| *pval = val; |
| |
| return i / 7; |
| } |
| |
| uint8_t nibble_to_num(char c) |
| { |
| switch (c) { |
| case '0': |
| return 0; |
| case '1': |
| return 1; |
| case '2': |
| return 2; |
| case '3': |
| return 3; |
| case '4': |
| return 4; |
| case '5': |
| return 5; |
| case '6': |
| return 6; |
| case '7': |
| return 7; |
| case '8': |
| return 8; |
| case '9': |
| return 9; |
| case 'a': |
| case 'A': |
| return 0xa; |
| case 'b': |
| case 'B': |
| return 0xb; |
| case 'c': |
| case 'C': |
| return 0xc; |
| case 'd': |
| case 'D': |
| return 0xd; |
| case 'e': |
| case 'E': |
| return 0xe; |
| case 'f': |
| case 'F': |
| return 0xf; |
| }; |
| return -1; |
| } |