diff --git a/application.py b/application.py index 42861a4..1e60bd8 100755 --- a/application.py +++ b/application.py @@ -13,7 +13,7 @@ import mode.console, mode.consolemini import mode.c, mode.python, mode.perl, mode.nasm, mode.sh, mode.sql, mode.java import mode.lisp, mode.elisp, mode.scheme, mode.ocaml import mode.blame, mode.diff, mode.dir -import mode.xml, mode.tt, mode.css, mode.javascript, mode.html +import mode.xml, mode.tt, mode.css, mode.javascript, mode.html, mode.hex import mode.text, mode.text2, mode.mutt import mode.bds import mode.rst @@ -111,6 +111,7 @@ class Application(object): 'bds': mode.bds.BDS, 'rst': mode.rst.RST, 'java': mode.java.Java, + 'hex': mode.hex.Hex, 'ocaml': mode.ocaml.Ocaml, @@ -260,7 +261,7 @@ class Application(object): return (slot.height, slot.width) # files and stuff - def open_path(self, path, cipher=None, password=None): + def open_path(self, path, binary=False, cipher=None, password=None): path = os.path.abspath(os.path.realpath(util.expand_tilde(path))) b = self.get_buffer_by_path(path) if b is None: @@ -276,7 +277,10 @@ class Application(object): mode_name = None if cipher is None: if not os.path.exists(path) or os.path.isfile(path): - b = buffer2.FileBuffer(path, name=name) + if binary: + b = buffer2.BinaryBuffer(path, name=name) + else: + b = buffer2.FileBuffer(path, name=name) elif os.path.isdir(path): b = buffer2.DirBuffer(path, name=name) mode_name = 'dir' @@ -786,9 +790,12 @@ def open_aes_file(path, nl, name=None): return buffer2.AesBuffer(path, p, nl, name) else: raise Exception, "can't open %r; unsupported file type" % path -def open_plain_file(path, nl, name=None): +def open_plain_file(path, nl, name=None, binary=False): if os.path.isfile(path) or not os.path.exists(path): - return buffer2.FileBuffer(path, nl, name) + if binary: + return buffer2.BinaryBuffer(path, nl, name) + else: + return buffer2.FileBuffer(path, nl, name) elif os.path.isdir(path): return buffer2.DirBuffer(path, nl, name) else: @@ -806,7 +813,10 @@ if __name__ == "__main__": parser.set_defaults(mode=None) parser.set_defaults(cipher='none') parser.set_defaults(linetype='unix') + parser.set_defaults(binary=False) + parser.add_option('-b', '--binary', dest='binary', action='store_true', + help='open file(s) in hex binary mode') parser.add_option('-d', '--debug', dest='debug', action='store_true', help='run in debug mode') parser.add_option('-e', '--encrypt', dest='cipher', metavar='CIPHER', @@ -863,7 +873,7 @@ if __name__ == "__main__": i += 1 auxname = '%s/%d' % (name, i) name = auxname - b = f(path, nl, name) + b = f(path, nl, name, opts.binary) b.open() buffers.append(b) paths.add(path) diff --git a/buffer2.py b/buffer2.py index 612e215..67f9639 100644 --- a/buffer2.py +++ b/buffer2.py @@ -1,4 +1,4 @@ -import datetime, grp, md5, os, pwd, re, sets, shutil, stat +import datetime, grp, md5, os, pwd, re, sets, shutil, stat, string import aes, dirutil, regex, highlight2 from point2 import Point @@ -478,6 +478,43 @@ class AesBuffer(FileBuffer): def write_filter(self, data): return aes.encrypt_data(data, self.password) +class BinaryBuffer(FileBuffer): + btype = 'binfile' + def __init__(self, path, nl='\n', name=None, numbytes=2): + '''fb = FileBuffer(path)''' + FileBuffer.__init__(self, path, nl, name) + self.numbytes = numbytes + def read_filter(self, data): + lines = [] + i = 0 + while i < len(data): + j = 0 + words = [] + while j < self.numbytes * 8 and i + j < len(data): + nibbles = [] + for c in data[i + j:i + j + 8]: + nibbles.append(string.hexdigits[ord(c) / 16]) + nibbles.append(string.hexdigits[ord(c) % 16]) + words.append(''.join(nibbles)) + j += 8 + lines.append(' '.join(words)) + i += self.numbytes * 8 + return '\n'.join(lines) + def write_filter(self, data): + bytes = [] + lastc = None + for c in data: + if c not in '0123456789abcdefABCDEF': + pass + elif lastc is None: + lastc = c + else: + bytes.append(chr(int(lastc + c, 16))) + lastc = None + if lastc is not None: + bytes.append(chr(int(lastc + '0', 16))) + return ''.join(bytes) + class DirBuffer(Buffer): btype = 'dir' def __init__(self, path, nl='\n', name=None): diff --git a/mode/hex.py b/mode/hex.py new file mode 100644 index 0000000..454b512 --- /dev/null +++ b/mode/hex.py @@ -0,0 +1,21 @@ +import color, mode2 +from lex3 import Grammar, PatternRule, RegionRule + +class HexGrammar(Grammar): + rules = [ + PatternRule(r'zero', r"00"), + PatternRule(r'printable', r"[2-7][0-9a-f]"), + PatternRule(r'byte', r'[0-f][0-f]'), + ] + +class Hex(mode2.Fundamental): + grammar = HexGrammar + colors = { + 'zero': ('magenta', 'default'), + 'printable': ('green', 'default'), + 'byte': ('white', 'default'), + } + def __init__(self, w): + mode2.Fundamental.__init__(self, w) + def name(self): + return "Hex"