blob: 6d46e6bd2a157eb0d183b03a8ec2f9d7f389becd [file] [log] [blame]
/* 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;
}