"""binhex - Macintosh binhex compression/decompression
easy interface:
binhex(inputfilename, outputfilename)
hexbin(inputfilename, outputfilename)
"""

#
# Jack Jansen, CWI, August 1995.
#
# The module is supposed to be as compatible as possible. Especially the
# easy interface should work "as expected" on any platform.
# XXXX Note: currently, textfiles appear in mac-form on all platforms.
# We seem to lack a simple character-translate in python.
# (we should probably use ISO-Latin-1 on all but the mac platform).
# XXXX The simeple routines are too simple: they expect to hold the complete
# files in-core. Should be fixed.
# XXXX It would be nice to handle AppleDouble format on unix
# (for servers serving macs).
# XXXX I don't understand what happens when you get 0x90 times the same byte on
# input. The resulting code (xx 90 90) would appear to be interpreted as an
# escaped *value* of 0x90. All coders I've seen appear to ignore this nicety...
#
import sys
import os
import struct
import string
import binascii
	
Error = 'binhex.Error'

# States (what have we written)
[_DID_HEADER, _DID_DATA, _DID_RSRC] = range(3)

# Various constants
REASONABLY_LARGE=32768	# Minimal amount we pass the rle-coder
LINELEN=64
RUNCHAR=chr(0x90)	# run-length introducer

#
# This code is no longer byte-order dependent

#
# Workarounds for non-mac machines.
if os.name == 'mac':
	import macfs
	import MacOS
	try:
		openrf = MacOS.openrf
	except AttributeError:
		# Backward compatability
		openrf = open
	
	def FInfo():
		return macfs.FInfo()
	
	def getfileinfo(name):
		finfo = macfs.FSSpec(name).GetFInfo()
		dir, file = os.path.split(name)
		# XXXX Get resource/data sizes
		fp = open(name, 'rb')
		fp.seek(0, 2)
		dlen = fp.tell()
		fp = openrf(name, '*rb')
		fp.seek(0, 2)
		rlen = fp.tell()
		return file, finfo, dlen, rlen
	
	def openrsrc(name, *mode):
		if not mode:
			mode = '*rb'
		else:
			mode = '*' + mode[0]
		return openrf(name, mode)

else:
	#
	# Glue code for non-macintosh useage
	#
	
	class FInfo:
		def __init__(self):
			self.Type = '????'
			self.Creator = '????'
			self.Flags = 0

	def getfileinfo(name):
		finfo = FInfo()
		# Quick check for textfile
		fp = open(name)
		data = open(name).read(256)
		for c in data:
			if not c in string.whitespace \
			    and (c<' ' or ord(c) > 0177):
				break
		else:
			finfo.Type = 'TEXT'
		fp.seek(0, 2)
		dsize = fp.tell()
		fp.close()
		dir, file = os.path.split(name)
		file = string.replace(file, ':', '-', 1)
		return file, finfo, dsize, 0

	class openrsrc:
		def __init__(self, *args):
			pass
	
		def read(self, *args):
			return ''
	
		def write(self, *args):
			pass
			
		def close(self):
			pass
	
class _Hqxcoderengine:
	"""Write data to the coder in 3-byte chunks"""
	
	def __init__(self, ofp):
		self.ofp = ofp
		self.data = ''
		self.hqxdata = ''
		self.linelen = LINELEN-1

	def write(self, data):
		self.data = self.data + data
		datalen = len(self.data)
		todo = (datalen/3)*3
		data = self.data[:todo]
		self.data = self.data[todo:]
		if not data:
			return
		self.hqxdata = self.hqxdata + binascii.b2a_hqx(data)
		self._flush(0)

	def _flush(self, force):
		first = 0
		while first <= len(self.hqxdata)-self.linelen:
			last = first + self.linelen
			self.ofp.write(self.hqxdata[first:last]+'\n')
			self.linelen = LINELEN
			first = last
		self.hqxdata = self.hqxdata[first:]
		if force:
			self.ofp.write(self.hqxdata + ':\n')

	def close(self):
		if self.data:
			self.hqxdata = \
			     self.hqxdata + binascii.b2a_hqx(self.data)
		self._flush(1)
		self.ofp.close()
		del self.ofp

class _Rlecoderengine:
	"""Write data to the RLE-coder in suitably large chunks"""

	def __init__(self, ofp):
		self.ofp = ofp
		self.data = ''

	def write(self, data):
		self.data = self.data + data
		if len(self.data) < REASONABLY_LARGE:
			return
		rledata = binascii.rlecode_hqx(self.data)
		self.ofp.write(rledata)
		self.data = ''

	def close(self):
		if self.data:
			rledata = binascii.rlecode_hqx(self.data)
			self.ofp.write(rledata)
		self.ofp.close()
		del self.ofp

class BinHex:
	def __init__(self, (name, finfo, dlen, rlen), ofp):
		if type(ofp) == type(''):
			ofname = ofp
			ofp = open(ofname, 'w')
			if os.name == 'mac':
				fss = macfs.FSSpec(ofname)
				fss.SetCreatorType('BnHq', 'TEXT')
		ofp.write('(This file must be converted with BinHex 4.0)\n\n:')
		hqxer = _Hqxcoderengine(ofp)
		self.ofp = _Rlecoderengine(hqxer)
		self.crc = 0
		if finfo == None:
			finfo = FInfo()
		self.dlen = dlen
		self.rlen = rlen
		self._writeinfo(name, finfo)
		self.state = _DID_HEADER

	def _writeinfo(self, name, finfo):
		name = name
		nl = len(name)
		if nl > 63:
			raise Error, 'Filename too long'
		d = chr(nl) + name + '\0'
		d2 = finfo.Type + finfo.Creator

		# Force all structs to be packed with big-endian
		d3 = struct.pack('>h', finfo.Flags)
		d4 = struct.pack('>ii', self.dlen, self.rlen)
		info = d + d2 + d3 + d4
		self._write(info)
		self._writecrc()

	def _write(self, data):
		self.crc = binascii.crc_hqx(data, self.crc)
		self.ofp.write(data)

	def _writecrc(self):
		# XXXX Should this be here??
		# self.crc = binascii.crc_hqx('\0\0', self.crc)
		self.ofp.write(struct.pack('>h', self.crc))
		self.crc = 0

	def write(self, data):
		if self.state != _DID_HEADER:
			raise Error, 'Writing data at the wrong time'
		self.dlen = self.dlen - len(data)
		self._write(data)

	def close_data(self):
		if self.dlen <> 0:
			raise Error, 'Incorrect data size, diff='+`self.rlen`
		self._writecrc()
		self.state = _DID_DATA

	def write_rsrc(self, data):
		if self.state < _DID_DATA:
			self.close_data()
		if self.state != _DID_DATA:
			raise Error, 'Writing resource data at the wrong time'
		self.rlen = self.rlen - len(data)
		self._write(data)

	def close(self):
		if self.state < _DID_DATA:
			self.close_data()
		if self.state != _DID_DATA:
			raise Error, 'Close at the wrong time'
		if self.rlen <> 0:
			raise Error, \
			      "Incorrect resource-datasize, diff="+`self.rlen`
		self._writecrc()
		self.ofp.close()
		self.state = None
		del self.ofp
	
def binhex(inp, out):
	"""(infilename, outfilename) - Create binhex-encoded copy of a file"""
	finfo = getfileinfo(inp)
	ofp = BinHex(finfo, out)
	
	ifp = open(inp, 'rb')
	# XXXX Do textfile translation on non-mac systems
	while 1:
		d = ifp.read(128000)
		if not d: break
		ofp.write(d)
	ofp.close_data()
	ifp.close()

	ifp = openrsrc(inp, 'rb')
	while 1:
		d = ifp.read(128000)
		if not d: break
		ofp.write_rsrc(d)
	ofp.close()
	ifp.close() 

class _Hqxdecoderengine:
	"""Read data via the decoder in 4-byte chunks"""
	
	def __init__(self, ifp):
		self.ifp = ifp
		self.eof = 0

	def read(self, totalwtd):
		"""Read at least wtd bytes (or until EOF)"""
		decdata = ''
		wtd = totalwtd
		#
		# The loop here is convoluted, since we don't really now how 
		# much to decode: there may be newlines in the incoming data.
		while wtd > 0:
			if self.eof: return decdata
			wtd = ((wtd+2)/3)*4
			data = self.ifp.read(wtd)
			#
			# Next problem: there may not be a complete number of
			# bytes in what we pass to a2b. Solve by yet another
			# loop.
			#
			while 1:
				try:
					decdatacur, self.eof = \
						    binascii.a2b_hqx(data)
					break
				except binascii.Incomplete:
					pass
				newdata = self.ifp.read(1)
				if not newdata:
					raise Error, \
					      'Premature EOF on binhex file'
				data = data + newdata
			decdata = decdata + decdatacur
			wtd = totalwtd - len(decdata)
			if not decdata and not self.eof:
				raise Error, 'Premature EOF on binhex file'
		return decdata

	def close(self):
		self.ifp.close()

class _Rledecoderengine:
	"""Read data via the RLE-coder"""

	def __init__(self, ifp):
		self.ifp = ifp
		self.pre_buffer = ''
		self.post_buffer = ''
		self.eof = 0

	def read(self, wtd):
		if wtd > len(self.post_buffer):
			self._fill(wtd-len(self.post_buffer))
		rv = self.post_buffer[:wtd]
		self.post_buffer = self.post_buffer[wtd:]
		return rv

	def _fill(self, wtd):
		self.pre_buffer = self.pre_buffer + self.ifp.read(wtd+4)
		if self.ifp.eof:
			self.post_buffer = self.post_buffer + \
				binascii.rledecode_hqx(self.pre_buffer)
			self.pre_buffer = ''
			return
			
		#
		# Obfuscated code ahead. We have to take care that we don't
		# end up with an orphaned RUNCHAR later on. So, we keep a couple
		# of bytes in the buffer, depending on what the end of
		# the buffer looks like:
		# '\220\0\220' - Keep 3 bytes: repeated \220 (escaped as \220\0)
		# '?\220' - Keep 2 bytes: repeated something-else
		# '\220\0' - Escaped \220: Keep 2 bytes.
		# '?\220?' - Complete repeat sequence: decode all
		# otherwise: keep 1 byte.
		#
		mark = len(self.pre_buffer)
		if self.pre_buffer[-3:] == RUNCHAR + '\0' + RUNCHAR:
			mark = mark - 3
		elif self.pre_buffer[-1] == RUNCHAR:
			mark = mark - 2
		elif self.pre_buffer[-2:] == RUNCHAR + '\0':
			mark = mark - 2
		elif self.pre_buffer[-2] == RUNCHAR:
			pass # Decode all
		else:
			mark = mark - 1

		self.post_buffer = self.post_buffer + \
			binascii.rledecode_hqx(self.pre_buffer[:mark])
		self.pre_buffer = self.pre_buffer[mark:]

	def close(self):
		self.ifp.close()

class HexBin:
	def __init__(self, ifp):
		if type(ifp) == type(''):
			ifp = open(ifp)
		#
		# Find initial colon.
		#
		while 1:
			ch = ifp.read(1)
			if not ch:
				raise Error, "No binhex data found"
			# Cater for \r\n terminated lines (which show up as \n\r, hence
			# all lines start with \r)
			if ch == '\r':
				continue
			if ch == ':':
				break
			if ch != '\n':
				dummy = ifp.readline()
			
		hqxifp = _Hqxdecoderengine(ifp)
		self.ifp = _Rledecoderengine(hqxifp)
		self.crc = 0
		self._readheader()
		
	def _read(self, len):
		data = self.ifp.read(len)
		self.crc = binascii.crc_hqx(data, self.crc)
		return data
		
	def _checkcrc(self):
		filecrc = struct.unpack('>h', self.ifp.read(2))[0] & 0xffff
		#self.crc = binascii.crc_hqx('\0\0', self.crc)
		# XXXX Is this needed??
		self.crc = self.crc & 0xffff
		if filecrc != self.crc:
			raise Error, 'CRC error, computed %x, read %x' \
			      %(self.crc, filecrc)
		self.crc = 0

	def _readheader(self):
		len = self._read(1)
		fname = self._read(ord(len))
		rest = self._read(1+4+4+2+4+4)
		self._checkcrc()
		
		type = rest[1:5]
		creator = rest[5:9]
		flags = struct.unpack('>h', rest[9:11])[0]
		self.dlen = struct.unpack('>l', rest[11:15])[0]
		self.rlen = struct.unpack('>l', rest[15:19])[0]
		
		self.FName = fname
		self.FInfo = FInfo()
		self.FInfo.Creator = creator
		self.FInfo.Type = type
		self.FInfo.Flags = flags
		
		self.state = _DID_HEADER
		
	def read(self, *n):
		if self.state != _DID_HEADER:
			raise Error, 'Read data at wrong time'
		if n:
			n = n[0]
			n = min(n, self.dlen)
		else:
			n = self.dlen
		rv = ''
		while len(rv) < n:
			rv = rv + self._read(n-len(rv))
		self.dlen = self.dlen - n
		return rv
		
	def close_data(self):
		if self.state != _DID_HEADER:
			raise Error, 'close_data at wrong time'
		if self.dlen:
			dummy = self._read(self.dlen)
		self._checkcrc()
		self.state = _DID_DATA
		
	def read_rsrc(self, *n):
		if self.state == _DID_HEADER:
			self.close_data()
		if self.state != _DID_DATA:
			raise Error, 'Read resource data at wrong time'
		if n:
			n = n[0]
			n = min(n, self.rlen)
		else:
			n = self.rlen
		self.rlen = self.rlen - n
		return self._read(n)
		
	def close(self):
		if self.rlen:
			dummy = self.read_rsrc(self.rlen)
		self._checkcrc()
		self.state = _DID_RSRC
		self.ifp.close()
		
def hexbin(inp, out):
	"""(infilename, outfilename) - Decode binhexed file"""
	ifp = HexBin(inp)
	finfo = ifp.FInfo
	if not out:
		out = ifp.FName
	if os.name == 'mac':
		ofss = macfs.FSSpec(out)
		out = ofss.as_pathname()

	ofp = open(out, 'wb')
	# XXXX Do translation on non-mac systems
	while 1:
		d = ifp.read(128000)
		if not d: break
		ofp.write(d)
	ofp.close()
	ifp.close_data()
	
	d = ifp.read_rsrc(128000)
	if d:
		ofp = openrsrc(out, 'wb')
		ofp.write(d)
		while 1:
			d = ifp.read_rsrc(128000)
			if not d: break
			ofp.write(d)
		ofp.close()

	if os.name == 'mac':
		nfinfo = ofss.GetFInfo()
		nfinfo.Creator = finfo.Creator
		nfinfo.Type = finfo.Type
		nfinfo.Flags = finfo.Flags
		ofss.SetFInfo(nfinfo)
	
	ifp.close()

def _test():
	if os.name == 'mac':
		fss, ok = macfs.PromptGetFile('File to convert:')
		if not ok:
			sys.exit(0)
		fname = fss.as_pathname()
	else:
		fname = sys.argv[1]
	binhex(fname, fname+'.hqx')
	hexbin(fname+'.hqx', fname+'.viahqx')
	#hexbin(fname, fname+'.unpacked')
	sys.exit(1)
	
if __name__ == '__main__':
	_test()
