bin

Bit stream reader / writer
git clone https://git.sinitax.com/sinitax/bin
Log | Files | Refs | LICENSE | sfeed.txt

unbin.c (1911B)


      1#include <stdlib.h>
      2#include <stdio.h>
      3#include <string.h>
      4#include <stdarg.h>
      5
      6#define ISFLAG(str, fshort, flong) (!strcmp(str, fshort) || !strcmp(str, flong))
      7
      8const char *usage = "USAGE: unbin [-r] [-s SKIP] [-n COUNT] [FILE]\n";
      9
     10void
     11die(const char *fmtstr, ...)
     12{
     13	va_list ap;
     14
     15	va_start(ap, fmtstr);
     16	vfprintf(stderr, fmtstr, ap);
     17	va_end(ap);
     18
     19	exit(EXIT_FAILURE);
     20}
     21
     22int
     23main(int argc, const char **argv)
     24{
     25	unsigned char byte, bit;
     26	size_t skip, cnt, pos;
     27	const char *filepath;
     28	int i, revbyte, cntset;
     29	char *end;
     30	FILE *f;
     31
     32	filepath = NULL;
     33	cnt = skip = 0;
     34	revbyte = cntset = 0;
     35
     36	for (i = 1; i < argc; i++) {
     37		if (ISFLAG(argv[i], "-s", "--skip")) {
     38			if (i++ == argc - 1) goto missing_arg;
     39			skip = strtoul(argv[i], &end, 0);
     40			if (end && *end) goto bad_arg;
     41		} else if (ISFLAG(argv[i], "-n", "--count")) {
     42			if (i++ == argc - 1) goto missing_arg;
     43			cnt = strtoul(argv[i], &end, 0);
     44			cntset = 1;
     45			if (end && *end) goto bad_arg;
     46		} else if (ISFLAG(argv[i], "-r", "--revb")) {
     47			revbyte = 1;
     48		} else if (ISFLAG(argv[i], "-h", "--help")) {
     49			die(usage);
     50		} else if (*argv[i] == '-') {
     51			die("Unknown flag: %s\n", argv[i]);
     52		} else if (filepath) {
     53			die("Too many files specified\n");
     54		} else {
     55			filepath = argv[i];
     56		}
     57	}
     58
     59	if (!filepath)
     60		f = stdin;
     61	else if (!(f = fopen(filepath, "r")))
     62		die("Failed to open file\n");
     63
     64	pos = 0;
     65	while (!cntset || pos < cnt + skip) {
     66		if (pos % 8 == 0) byte = 0;
     67		bit = fgetc(f);
     68		if (feof(f)) break;
     69		if (bit != '1' && bit != '0')
     70			continue;
     71		bit = (bit == '1');
     72		if (pos >= 0) {
     73			if (revbyte)
     74				byte |= bit << (pos % 8);
     75			else
     76				byte |= bit << (7 - pos % 8);
     77			if (pos % 8 == 7)
     78				putchar(byte);
     79		}
     80		pos += 1;
     81	}
     82	if (pos % 8 != 0)
     83		putchar(byte);
     84
     85	fclose(f);
     86
     87	return EXIT_SUCCESS;
     88
     89missing_arg:
     90	die("Flag %s expects an argument\n", argv[i]);
     91
     92bad_arg:
     93	die("Argument has unexpected value: %s\n", argv[i]);
     94}