Skip to content

Instantly share code, notes, and snippets.

@yinyin
Created June 5, 2012 08:18
Show Gist options
  • Save yinyin/2873582 to your computer and use it in GitHub Desktop.
Save yinyin/2873582 to your computer and use it in GitHub Desktop.
An quick utility to convert binary text (eg: 01010110) into binary file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#if (__APPLE__) || (USE_DARWIN)
#include <libkern/OSByteOrder.h>
#define htobe64(x) OSSwapHostToBigInt64(x)
#else
#include <endian.h>
#endif /* (__APPLE__) || (USE_DARWIN) */
#define MAX_BUFFER_SIZE (1024*1024)
#define _DUMP_DEBUG 0
#define _DUMP_STATE_TRANSIT 1
/* {{{ *** implement bit buffer */
typedef struct _T_BitBufferW {
void * buffer_ptr;
int current_size;
uint64_t imbb_buffer;
int imbb_remain;
} BitBufferW;
int init_bitbuffer_w(BitBufferW * inst, int max_size)
{
{
memset(inst, 0, sizeof(BitBufferW));
inst->current_size = 0;
inst->imbb_remain = 64;
}
{
int retcode;
void * p;
if( 0 != (retcode = posix_memalign(&p, ((128/8)/sizeof(void*))*sizeof(void *), max_size)) )
{
fprintf(stderr, "ERR: Failed on allocating memory (%d: %s) @[%s:%d]\n", retcode, strerror(retcode), __FILE__, __LINE__);
return -1;
}
memset(p, 0, max_size);
inst->buffer_ptr = p;
}
return 0;
}
int destory_bitbuffer_w(BitBufferW * inst)
{
free(inst->buffer_ptr);
inst->buffer_ptr = 0;
return 0;
}
int flush_bitbuffer_w(BitBufferW * inst, int seal)
{
uint64_t * tgt_p;
#if _DUMP_DEBUG
fprintf(stderr, "INFO: flush_bitbuffer_w(seal=%d, imbb_remain=%d) @[%s:%d]\n", seal, inst->imbb_remain, __FILE__, __LINE__);
#endif
if(1 == seal)
{
inst->imbb_buffer = (inst->imbb_buffer) << (inst->imbb_remain);
}
else if(0 != inst->imbb_remain)
{ return 1; }
tgt_p = (uint64_t *)(inst->buffer_ptr) + (inst->current_size / sizeof(uint64_t));
*tgt_p = htobe64(inst->imbb_buffer);
if(1 != seal)
{
inst->current_size += sizeof(uint64_t);
inst->imbb_remain = 64;
}
else
{
inst->current_size += ((64/8) - (inst->imbb_remain/8));
inst->imbb_remain = -1;
}
return 0;
}
int write_bitbuffer_w(BitBufferW * inst, uint64_t buf, int bitcount)
{
#if _DUMP_DEBUG
fprintf(stderr, "INFO: write_bitbuffer_w(buf=0x%016llX, bitcount=%d) @[%s:%d]\n", buf, bitcount, __FILE__, __LINE__);
#endif
if(-1 == inst->imbb_remain)
{ return 1; }
if(bitcount > 64)
{ bitcount = 64; }
if( (64 == bitcount) && (64 == inst->imbb_remain) )
{
inst->imbb_buffer = buf;
inst->imbb_remain = 0;
flush_bitbuffer_w(inst, 0);
}
else
{
int remain_bits;
remain_bits = bitcount;
while(remain_bits > 0) {
int writable;
uint64_t bits_togo;
writable = (inst->imbb_remain < remain_bits) ? inst->imbb_remain : remain_bits;
bits_togo = (buf >> (remain_bits - writable)) & ((1LL << writable) - 1LL);
inst->imbb_buffer = (inst->imbb_buffer << writable) | bits_togo;
inst->imbb_remain -= writable;
remain_bits -= writable;
flush_bitbuffer_w(inst, 0);
#if _DUMP_DEBUG
fprintf(stderr, "INFO: bits_togo=0x%016llX, writable=%d, result=0x%016llX, remain_bits=%d @[%s:%d]\n", bits_togo, writable, inst->imbb_buffer, remain_bits, __FILE__, __LINE__);
#endif
}
}
return 0;
}
/* }}} *** implement bit buffer */
/* {{{ *** implement reverse convert */
/* {{{ status transition table
--------
import re
IN_MAP = {'UNKNWN': 0, 'BINDGT': 1, 'DCHR': 2, 'DECDGT': 3, 'DSEPCHR': 4, 'XCHR': 5, 'HEXDGT': 6, 'LINECMMT': 7, 'BLKCMMTS': 8, 'BLKCMMTE': 9, 'STRQCHR': 10}
x = """
4 -default- 4
6 -default- 6
5 -default- 5
-------------
0 BINDGT 0
0 DCHR 1
0 XCHR 3
0 LINECMMT 5
0 BLKCMMTS 4
0 STRQCHR 6
1 DECDGT 1
1 DSEPCHR 2
1 LINECMMT 5
1 BLKCMMTS 4
1 STRQCHR 6
2 DECDGT 2
2 LINECMMT 5
2 BLKCMMTS 4
2 STRQCHR 6
3 HEXDGT 3
3 DECDGT 3
3 LINECMMT 5
3 BLKCMMTS 4
3 STRQCHR 6
4 BLKCMMTE 0
5 =END-STATE
6 STRQCHR 0
"""
max_state = 6
max_input = 10
r1 = re.compile("\s*([0-9]+)\s+([A-Z][A-Z0-9]*)\s+([0-9]+)\s*")
rE = re.compile("\s*([0-9]+)\s+-default-\s+([0-9]+)\s*")
result = [ [0 for i in range(1+max_state)] for j in range(1+max_input) ]
for l in x.split("\n"):
m = r1.match(l)
if m is not None:
try:
xf = int(m.group(1))
xt = int(m.group(3))
in_symb = m.group(2)
in_v = IN_MAP[in_symb]
result[in_v][xf] = xt
except Exception as e:
print ">>r1> line = %r" % (l,)
raise e
continue
m = rE.match(l)
if m is not None:
try:
xf = int(m.group(1))
nd = int(m.group(2))
for j in range(1+max_input):
result[j][xf] = nd
except Exception as e:
print ">>rE> line = %r" % (l,)
raise e
continue
for in_v in range(1+max_input):
print "\t{", ", ".join([ ("%2d"%xt) for xt in result[in_v] ]), "},"
--------
}}} */
#define BXD_IN_UNKNWN 0
#define BXD_IN_BINDGT 1
#define BXD_IN_DCHR 2
#define BXD_IN_DECDGT 3
#define BXD_IN_DSEPCHR 4
#define BXD_IN_XCHR 5
#define BXD_IN_HEXDGT 6
#define BXD_IN_LINECMMT 7
#define BXD_IN_BLKCMMTS 8
#define BXD_IN_BLKCMMTE 9
#define BXD_IN_STRQCHR 10
static int BXD_SYNTAX_TRANSITION_TBL[11][7] = {
{ 0, 0, 0, 0, 4, 5, 6 },
{ 0, 0, 0, 0, 4, 5, 6 },
{ 1, 0, 0, 0, 4, 5, 6 },
{ 0, 1, 2, 3, 4, 5, 6 },
{ 0, 2, 0, 0, 4, 5, 6 },
{ 3, 0, 0, 0, 4, 5, 6 },
{ 0, 0, 0, 3, 4, 5, 6 },
{ 5, 5, 5, 5, 4, 5, 6 },
{ 4, 4, 4, 4, 4, 5, 6 },
{ 0, 0, 0, 0, 0, 5, 6 },
{ 6, 6, 6, 6, 4, 5, 0 }
};
int translate_input_for_bxd_reverse(char ch, int current_state, int *vp)
{
int result;
int value;
result = -1;
value = 0;
if(0 == current_state)
{
if( ('0' == ch) || ('1' == ch) )
{
value = (int)(ch - '0');
result = BXD_IN_BINDGT;
}
}
else if(3 == current_state)
{
if( ('0' <= ch) && ('9' >= ch) )
{
value = (int)(ch - '0');
result = BXD_IN_HEXDGT;
}
else if( ('a' <= ch) && ('f' >= ch) )
{
value = (int)(ch - 'a') + 10;
result = BXD_IN_HEXDGT;
}
else if( ('A' <= ch) && ('F' >= ch) )
{
value = (int)(ch - 'A') + 10;
result = BXD_IN_HEXDGT;
}
}
else if( (1 == current_state) || (2 == current_state) )
{
if( ('0' <= ch) && ('9' >= ch) )
{
value = (int)(ch - '0');
result = BXD_IN_DECDGT;
}
}
else if(6 == current_state)
{
if('"' == ch)
{
result = BXD_IN_STRQCHR;
}
else
{
value = (int)(ch);
result = BXD_IN_UNKNWN;
}
}
if(-1 == result)
{
result = BXD_IN_UNKNWN;
if('d' == ch)
{ result = BXD_IN_DCHR; }
else if( ('/' == ch) || (',' == ch) )
{ result = BXD_IN_DSEPCHR; }
else if('x' == ch)
{ result = BXD_IN_XCHR; }
else if('(' == ch)
{ result = BXD_IN_BLKCMMTS; }
else if(')' == ch)
{ result = BXD_IN_BLKCMMTE; }
else if('#' == ch)
{ result = BXD_IN_LINECMMT; }
else if('"' == ch)
{ result = BXD_IN_STRQCHR; }
}
if(NULL != vp)
{ *vp = value; }
return result;
}
int translate_line_to_bitbuffer_w(char * linebuf, char * linebuf_boundary, BitBufferW * inst)
{
int current_state;
uint64_t dec_valbuffer;
int dec_bitcount;
char ch;
current_state = 0;
dec_valbuffer = 0LL;
dec_bitcount = 0;
while('\0' != (ch = *linebuf)) {
int val;
int incode;
int next_state;
incode = translate_input_for_bxd_reverse(ch, current_state, &val);
next_state = BXD_SYNTAX_TRANSITION_TBL[incode][current_state];
#if _DUMP_DEBUG && _DUMP_STATE_TRANSIT
fprintf(stderr, "INFO: state-transit: c=%d, n=%d, i=%d @[%s:%d]\n", current_state, next_state, incode, __FILE__, __LINE__);
#endif
/* {{{ arc process */
if( ((0 == current_state) && (0 == next_state)) && (BXD_IN_BINDGT == incode) )
{ /* binary */
write_bitbuffer_w(inst, (uint64_t)(val), 1);
#if _DUMP_DEBUG
fprintf(stderr, "INFO: written binary v=%d @[%s:%d]\n", val, __FILE__, __LINE__);
#endif
}
else if( (0 == current_state) && (1 == next_state) )
{ /* decimal start */
dec_valbuffer = 0LL;
dec_bitcount = 0;
}
else if( (1 == current_state) && (1 == next_state) )
{ /* decimal value */
dec_valbuffer = (dec_valbuffer * 10LL) + ((uint64_t)(val));
}
else if( (2 == current_state) && (2 == next_state) )
{ /* decimal bit number */
dec_bitcount = (dec_bitcount * 10) + val;
}
else if( ( (1 == current_state) || (2 == current_state) )
&& ( (1 != next_state) && (2 != next_state) ) )
{ /* decimal end */
if(0 == dec_bitcount)
{ dec_bitcount = 8; }
write_bitbuffer_w(inst, dec_valbuffer, dec_bitcount);
#if _DUMP_DEBUG
fprintf(stderr, "INFO: written decimal v=%llu, bit=%d @[%s:%d]\n", dec_valbuffer, dec_bitcount, __FILE__, __LINE__);
#endif
}
else if( (3 == current_state) && (3 == next_state) )
{ /* hex */
write_bitbuffer_w(inst, (uint64_t)(val), 4);
#if _DUMP_DEBUG
fprintf(stderr, "INFO: written hex v=0x%X @[%s:%d]\n", val, __FILE__, __LINE__);
#endif
}
else if( (6 == current_state) && (6 == next_state) )
{ /* string */
write_bitbuffer_w(inst, (uint64_t)(val), 8);
#if _DUMP_DEBUG
fprintf(stderr, "INFO: written char v=%c @[%s:%d]\n", (char)(val), __FILE__, __LINE__);
#endif
}
/* }}} arc process */
current_state = next_state;
linebuf++;
if(linebuf >= linebuf_boundary)
{ break; }
}
return 0;
}
int translate_to_binaryimage(FILE * fp_in, FILE * fp_out)
{
BitBufferW instobj;
char linebuf[2048];
char * linebuf_boundary;
linebuf_boundary = linebuf + 2048;
init_bitbuffer_w(&instobj, MAX_BUFFER_SIZE);
while(NULL != fgets(linebuf, 2048, fp_in)) {
#if _DUMP_DEBUG
fprintf(stderr, "INFO: read line [%s] @[%s:%d]\n", linebuf, __FILE__, __LINE__);
#endif
translate_line_to_bitbuffer_w(linebuf, linebuf_boundary, &instobj);
}
flush_bitbuffer_w(&instobj, 1);
fwrite(instobj.buffer_ptr, instobj.current_size, 1, fp_out);
return 0;
}
/* }}} *** implement reverse convert */
int main(int argc, char ** argv)
{
int optcode;
int flag_reverconv;
char * input_filepath;
char * output_filepath;
FILE * fp_in;
FILE * fp_out;
flag_reverconv = 0;
input_filepath = NULL;
output_filepath = NULL;
while( -1 != (optcode = getopt(argc, argv, "ro:")) ) {
switch(optcode)
{
case 'r':
flag_reverconv = 1;
break;
case 'o':
output_filepath = optarg;
break;
default:
printf("Usage: [-r] [-o OUTPUT_FILE] [INPUT_FILE]\n\n");
exit(1);
}
}
if(optind < argc)
{
input_filepath = argv[optind];
}
if(NULL == input_filepath)
{
fp_in = stdin;
}
else
{
if( NULL == (fp_in = fopen(input_filepath, "rb")) )
{
fprintf(stderr, "ERR: cannot open input file: [%s]\n", input_filepath);
exit(2);
}
}
if(NULL == output_filepath)
{
fp_out = stdout;
}
else
{
if( NULL == (fp_out = fopen(output_filepath, "wb")) )
{
fprintf(stderr, "ERR: cannot open output file: [%s]\n", output_filepath);
exit(2);
}
}
if(0 == flag_reverconv)
{
fprintf(stderr, "ERR: not implement yet.\n");
exit(2);
}
else
{
translate_to_binaryimage(fp_in, fp_out);
if(NULL != input_filepath)
{ fclose(fp_in); }
if(NULL != output_filepath)
{ fclose(fp_out); }
}
return 0;
}
/*
vim: ts=4 sw=4 ai nowrap
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment