#!/usr/local/bin/pythonw
# coding: iso-8859-1
# Copyright © 2009 by Amos Newcombe
# 
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along with this program.  If not, see <http://www.gnu.org/licenses/>.

'''hex: contents of a file in hexadecimal
'''

import os
from commander.commander import commander

class hex(commander):
	'''translate file contents to hexidecimal output format
	'''
	
# 	def __init__(self, lsLine):
# 		commander.__init__(self, lsLine)
# 		print self.lsArgs
	
	def options(self):
		'Populate the option parser (self.optParser) with available options.'
		self.optParser.add_option('-f', '--from',
			action='store', dest='nFrom', type='int', default=0,
			metavar='N', help='set the start to byte #N (default 0: beginning of file)'
		)
		self.optParser.add_option('-l', '--lim',
			action='store', dest='nLim', type='int', default=0,
			metavar='N', help='set the end to byte #N (default -0: end of file)'
		)
	
	def main1(self, sArg):
		cb = os.stat(sArg).st_size
		nFrom, nLim = self.getLimits(cb)
		s = file(sArg, 'rU').read(nLim)[nFrom:]
# 		print 'read %d chars from %s' % (len(s), sArg)
		i = 0
		while i < nLim - nFrom:
			s0, s1 = s[i:i+8], s[i+8:i+16]
			if not s0: break
			sOut = '%08x  ' % (i + nFrom)
			for ch in s0: sOut += '%02x ' % ord(ch)
			sOut += '   ' * (8 - len(s0))
			sOut += '| '
			for ch in s1: sOut += '%02x ' % ord(ch)
			sOut += '   ' * (8 - len(s1)) + ' '
			sOut += ''.join([self.clean(ch) for ch in s0+s1])
			print sOut
			i += 16
	
	def getLimits(self, cb):
# 		print self.opt.nFrom, self.opt.nLim, cb
		nFrom = self.opt.nFrom
		if nFrom < 0: nFrom += cb
		if nFrom < 0: nFrom  = 0
		if cb <= nFrom: nFrom = cb - 1
		nLim = self.opt.nLim
		if nLim <= 0: nLim += cb
		if nLim <  0: nLim  = 0
		if cb < nLim: nLim = cb
		if nLim <= nFrom: nFrom, nLim = nLim, nFrom
# 		print nFrom, nLim
		return nFrom, nLim
	
	def clean(self, ch):
		if (ord(ch) < 32) or (127 < ord(ch)): ch = '.'
		return ch

if __name__ == '__main__':
	
	import sys
	hex(sys.argv).main()
