#!/usr/bin/env python

import os
import sys
import stat
import string

record_style=''
bigendian=littleendian=0
word_size=-1

def usage(retval):
	sys.stderr.write('Usage: %s [-r recordfile|-f fixedreclen|-o] -w word_size [-h]\n' % sys.argv[0])
	sys.stderr.write('-r recordfile means to read a series of record lengths from file recordfile\n')
	sys.stderr.write('-f fixedreclen means to assume a fixed record length\n')
	sys.stderr.write('-o means to assume the file has a single record\n')
	sys.stderr.write('-w wordsize specifies the size of the integers used in the framing.  Common values are 4 and 8\n')
	sys.stderr.write('-b says to assume big endian byte ordering of the integers used for framing\n')
	sys.stderr.write('-l says to assume little endian byte ordering of the integers used for framing\n')
	sys.stderr.write('-h shows help\n')
	sys.exit(retval)

while sys.argv[1:]:
#	sys.stderr.write('Examining argument %s\n' % sys.argv[1])
	if sys.argv[1] == '-r' and sys.argv[2:]:
		if record_style:
			sys.stderr.write('You must use exactly one of -r, -f or -o\n')
			usage(1)
		record_length_filename = sys.argv[2]
		del sys.argv[1]
	elif sys.argv[1] == '-f' and sys.argv[2]:
		if record_style:
			sys.stderr.write('You must use exactly one of -r, -f or -o\n')
			usage(1)
		record_style='fixed'
		fixed_length_rec_len = string.atoi(sys.argv[2])
		del sys.argv[1]
	elif sys.argv[1] == '-o' and sys.argv[2]:
		if record_style:
			sys.stderr.write('You must use exactly one of -r, -f or -o\n')
			usage(1)
		record_style='one'
	elif sys.argv[1] == '-w' and sys.argv[2]:
		word_size=string.atoi(sys.argv[2])
		del sys.argv[1]
	elif sys.argv[1] == '-b':
		bigendian=1
	elif sys.argv[1] == '-l':
		littleendian=1
	elif sys.argv[1] == '-h':
		usage(0)
	else:
		usage(1)
	del sys.argv[1]

if not record_style:
	sys.stderr.write('You must use exactly one of -r, -f or -o\n')
	usage(1)

if bigendian + littleendian != 1:
	sys.stderr.write('You must use exactly one of -b, or -l\n')
	usage(1)

if word_size == -1:
	sys.stderr.write('Sorry, you must give a word size with -w.  Common values are 4 and 8\n')
	usage(1)

if record_style == 'file':
	# yield a series of integers from a file
	def record_lengths():
		while 1:
			line = open(record_length_filename, 'r')
			if not line:
				break
			yield string.atoi(line)
elif record_style == 'fixed':
	# yield a series of integers of the same value
	def record_lengths():
		while 1:
			yield fixed_length_rec_len
elif record_style == 'one':
	# yield a a single integer that is length of the file.  Note that we
	# won't always be able to get the file length this way.  Basically, <
	# good, | bad.
	def record_lengths():
		# 0 is stdin, of course
		stat_buf = os.fstat(0)
		yield stat_buf[stat.ST_SIZE]
else:
	sys.stderr.write('Internal error: bad record_style\n')
	usage(1)

def take_apart_int(integer):
	list = []
	temp = integer
	for i in range(word_size):
		(quotient, remainder) = divmod(temp, 256)
		temp = quotient
		list.append(remainder)
	return map(chr,list)

def write_int(i):
	# most significant first
	list = take_apart_int(i)
	if bigendian:
		list.reverse()
	sys.stdout.write(string.joinfields(list,''))

for record_len in record_lengths():
	buffer = sys.stdin.read(record_len)
	if not buffer:
		break
	if len(buffer) != record_len:
		sys.stderr.write('Bad file length, given the options you have specified\n')
		sys.exit(1)
	write_int(record_len)
	sys.stdout.write(buffer)
	write_int(record_len)

