Created
June 5, 2012 08:18
-
-
Save yinyin/2873582 to your computer and use it in GitHub Desktop.
An quick utility to convert binary text (eg: 01010110) into binary file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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