#!/usr/local/bin/python

import sys
import string

bigendian=littleendian=0

blocksize = 1024 * 1024

wordsize = 4

maxreclen = -1

def usage():
	sys.stderr.write('Usage: %s [-b] [-l] [-w wordsize] [-m max_record_length]\n' % sys.argv[0])
	sys.stderr.write('\nThis program is intended to strip off fortran framed records\n')
	sys.stderr.write('With -b, the program will assume 4 byte, big endian framing\n')
	sys.stderr.write('With -l, the program will assume 4 byte, little endian framing\n')
	sys.stderr.write('There is no default; You must specify either -b or -l\n')
	sys.stderr.write('\nWith -w 8, the program will assume 8 byte words, for example.  The default is 4\n')
	sys.stderr.write('\nWith -m 65536, the program will error out if any records are longer than 65536 bytes\n')
	sys.exit(1)

while sys.argv[1:]:
	if sys.argv[1] == '-b':
		bigendian = 1
		del sys.argv[1]
	elif sys.argv[1] == '-l':
		littleendian = 1
		del sys.argv[1]
	elif sys.argv[1] == '-w' and sys.argv[2:]:
		wordsize = string.atoi(sys.argv[2])
		del sys.argv[1]
		del sys.argv[1]
	elif sys.argv[1] == '-m' and sys.argv[2:]:
		maxreclen = string.atoi(sys.argv[2])
		del sys.argv[1]
		del sys.argv[1]
	else:
		usage()

if bigendian + littleendian != 1:
	usage()

def acc(bytes):
	accumulator = 0L
	for byteno in range(len(bytes)):
		accumulator = accumulator * 256L + bytes[byteno]
	return accumulator

def readbyte(eofok):
	if eofok:
		ch = sys.stdin.read(1)
		if len(ch) == 0:
			sys.stderr.write('Normal termination\n')
			sys.exit(0)
		else:
			return ord(ch)
	else:
		ch = sys.stdin.read(1)
		if len(ch) == 0:
			sys.stderr.write('Abnormal termination 1\n')
			sys.exit(1)
		else:
			return ord(ch)
		
def readbig(n,eofok):
	bytes = []
	for i in range(n):
		bytes.append(readbyte(i == 0 and eofok))
	return acc(bytes)

def readlittle(n,eofok):
	bytes = []
	for i in range(n):
		bytes.append(readbyte(i == 0 and eofok))
	bytes.reverse()
	return acc(bytes)

recno = 0
while 1:
	if bigendian:
		count1 = readbig(wordsize,1)
	elif littleendian:
		count1 = readlittle(wordsize,1)
	else:
		sys.stderr.write('Internal error: no big or little endian specified\n')
		sys.exit(1)
	if maxreclen != -1 and count1 > maxreclen:
		sys.stderr.write('Record length %d exceeds cutoff value of %d.  Abnormal termination\n' % (count1, maxreclen))
		sys.exit(1)
	sys.stderr.write('Record %d is length %d\n' % (recno, count1))
	(blocks,remainder) = divmod(count1,blocksize)
	for blockno in xrange(blocks):
		buf = sys.stdin.read(blocksize)
		if len(buf) != blocksize:
			sys.stderr.write('Abnormal termination 2\n')
			sys.exit(1)
		sys.stdout.write(buf)
	if remainder != 0:
		buf = sys.stdin.read(remainder)
		if len(buf) != remainder:
			sys.stderr.write('Abnormal termination 3\n')
			sys.exit(1)
		sys.stdout.write(buf)
	if bigendian:
		count2 = readbig(wordsize,0)
	elif littleendian:
		count2 = readlittle(wordsize,0)
	else:
		sys.stderr.write('Internal error: no big or little endian specified\n')
		sys.exit(1)
	if count1 != count2:
		sys.stderr.write('Sorry, framing does not match up.  Maybe you should try the other byte order or a different word size?\n')
		sys.exit(1)
	recno += 1


