#! /usr/bin/env python import os import sys import numpy import math import struct import argparse def BinRead(filin,filout='',verbose=0): #{{{ print "reading binary file." f=open(filin,'rb') if filout: sys.stdout=open(filout,'w') while True: try: #Step 1: read size of record name recordnamesize=struct.unpack('i',f.read(struct.calcsize('i')))[0] except struct.error as e: print "probable EOF: %s" % e break print "============================================================================" if verbose>2: print "\nrecordnamesize = \"%d\"" % (recordnamesize) recordname=struct.unpack('%ds' % recordnamesize,f.read(recordnamesize))[0] print "field: %s" % recordname #Step 2: read the data itself. #first read length of record reclen=struct.unpack('i',f.read(struct.calcsize('i')))[0] if verbose>1: print "reclen = %d" % reclen #read data code: code=struct.unpack('i',f.read(struct.calcsize('i')))[0] #print "code = %d (%s)" % (code,CodeToFormat(code)) print "Format = %s" % CodeToFormat(code) if code == FormatToCode('Boolean'): # bval=struct.unpack('b',f.read(reclen-struct.calcsize('i')))[0] bval=struct.unpack('i',f.read(reclen-struct.calcsize('i')))[0] print "value = %d" % bval elif code == FormatToCode('Integer'): ival=struct.unpack('i',f.read(reclen-struct.calcsize('i')))[0] print "value = %d" % ival elif code == FormatToCode('Double'): dval=struct.unpack('d',f.read(reclen-struct.calcsize('i')))[0] print "value = %f" % dval elif code == FormatToCode('String'): strlen=struct.unpack('i',f.read(struct.calcsize('i')))[0] if verbose>1: print "strlen = %d" % strlen sval=struct.unpack('%ds' % strlen,f.read(strlen))[0] print "value = '%s'" % sval elif code == FormatToCode('BooleanMat'): #read matrix type: mattype=struct.unpack('i',f.read(struct.calcsize('i')))[0] print "mattype = %d" % mattype #now read matrix s=[0,0] s[0]=struct.unpack('i',f.read(struct.calcsize('i')))[0] s[1]=struct.unpack('i',f.read(struct.calcsize('i')))[0] print "size = [%dx%d]" % (s[0],s[1]) data=numpy.zeros((s[0],s[1])) for i in xrange(s[0]): for j in xrange(s[1]): data[i][j]=struct.unpack('d',f.read(struct.calcsize('d')))[0] #get to the "c" convention, hence the transpose if verbose>2: print "data[%d,%d] = %f" % (i,j,data[i][j]) elif code == FormatToCode('IntMat'): #read matrix type: mattype=struct.unpack('i',f.read(struct.calcsize('i')))[0] print "mattype = %d" % mattype #now read matrix s=[0,0] s[0]=struct.unpack('i',f.read(struct.calcsize('i')))[0] s[1]=struct.unpack('i',f.read(struct.calcsize('i')))[0] print "size = [%dx%d]" % (s[0],s[1]) data=numpy.zeros((s[0],s[1])) for i in xrange(s[0]): for j in xrange(s[1]): data[i][j]=struct.unpack('d',f.read(struct.calcsize('d')))[0] #get to the "c" convention, hence the transpose if verbose>2: print "data[%d,%d] = %f" % (i,j,data[i][j]) elif code == FormatToCode('DoubleMat'): #read matrix type: mattype=struct.unpack('i',f.read(struct.calcsize('i')))[0] print "mattype = %d" % mattype #now read matrix s=[0,0] s[0]=struct.unpack('i',f.read(struct.calcsize('i')))[0] s[1]=struct.unpack('i',f.read(struct.calcsize('i')))[0] print "size = [%dx%d]" % (s[0],s[1]) data=numpy.zeros((s[0],s[1])) for i in xrange(s[0]): for j in xrange(s[1]): data[i][j]=struct.unpack('d',f.read(struct.calcsize('d')))[0] #get to the "c" convention, hence the transpose if verbose>2: print "data[%d,%d] = %f" % (i,j,data[i][j]) elif code == FormatToCode('MatArray'): f.seek(reclen-4,1) print "skipping %d bytes for code %d." % (code, reclen-4) elif code == FormatToCode('StringArray'): f.seek(reclen-4,1) print "skipping %d bytes for code %d." % (code, reclen-4) else: raise TypeError('BinRead error message: data type: %d not supported yet! (%s)' % (code,recordname)) f.close() #}}} def FormatToCode(format): # {{{ """ This routine takes the format string, and hardcodes it into an integer, which is passed along the record, in order to identify the nature of the dataset being sent. """ if strcmpi(format,'Boolean'): code=1 elif strcmpi(format,'Integer'): code=2 elif strcmpi(format,'Double'): code=3 elif strcmpi(format,'String'): code=4 elif strcmpi(format,'BooleanMat'): code=5 elif strcmpi(format,'IntMat'): code=6 elif strcmpi(format,'DoubleMat'): code=7 elif strcmpi(format,'MatArray'): code=8 elif strcmpi(format,'StringArray'): code=9 else: raise InputError('FormatToCode error message: data type not supported yet!') return code # }}} def CodeToFormat(code): # {{{ """ This routine takes the format string, and hardcodes it into an integer, which is passed along the record, in order to identify the nature of the dataset being sent. """ if code==1: format='Boolean' elif code==2: format='Integer' elif code==3: format='Double' elif code==4: format='String' elif code==5: format='BooleanMat' elif code==6: format='IntMat' elif code==7: format='DoubleMat' elif code==8: format='MatArray' elif code==9: format='StringArray' else: raise TypeError('FormatToCode error message: code %d not supported yet!' %code) return format # }}} if __name__ == '__main__': #{{{ if 'PYTHONSTARTUP' in os.environ: PYTHONSTARTUP=os.environ['PYTHONSTARTUP'] print 'PYTHONSTARTUP =',PYTHONSTARTUP if os.path.exists(PYTHONSTARTUP): try: execfile(PYTHONSTARTUP) except Exception as e: print "PYTHONSTARTUP error: ",e else: print "PYTHONSTARTUP file '%s' does not exist." % PYTHONSTARTUP parser = argparse.ArgumentParser(description='BinRead - function to read binary input file.') parser.add_argument('-f','--filin', help='name of binary input file', default='') parser.add_argument('-o','--filout', help='optional name of text output file', default='') parser.add_argument('-v','--verbose', help='optional level of output', default=0) args = parser.parse_args() from MatlabFuncs import * BinRead(args.filin, args.filout,args.verbose) #}}}