From 9fd4ae328b21c10fdb57d449c769939a9b1ad933 Mon Sep 17 00:00:00 2001 From: moculus Date: Fri, 11 Apr 2008 14:22:50 +0000 Subject: [PATCH] --HG-- branch : pmacs2 --- buffer.py | 5 ++ mode/hex.py | 142 +++++++++++++++++++++++++--------------------------- 2 files changed, 73 insertions(+), 74 deletions(-) diff --git a/buffer.py b/buffer.py index 1d24e82..82ff14b 100644 --- a/buffer.py +++ b/buffer.py @@ -551,6 +551,11 @@ class Binary32Buffer(FileBuffer): return (ix // self.groupsize) * self.grouppad + ix * (2 + self.bytepad) else: return None + def datax_to_cursory(self, ix): + return ix // (self.groupsize * self.numgroups) + + def get_address(self, cy, ix): + return (cy * self.numgroups * self.groupsize) + ix def overwrite_char(self, p, c, act=ACT_NORM, force=False): ix = self.cursorx_to_datax(p.y, p.x) diff --git a/mode/hex.py b/mode/hex.py index 3aa1fc2..a01fba9 100644 --- a/mode/hex.py +++ b/mode/hex.py @@ -72,15 +72,23 @@ class Hex(mode.Fundamental): self.add_action_and_bindings(HexBackwardWord(), ('M-b', 'M-L_ARROW',)) self.add_action_and_bindings(HexStartOfLine(), ('C-a', 'HOME',)) self.add_action_and_bindings(HexEndOfLine(), ('C-e', 'END',)) - self.add_action_and_bindings(GotoWord(), ('M-g',)) + + self.add_action_and_bindings(HexRead('int', 'i'), ('C-u i',)) + self.add_action_and_bindings(HexRead('uint', 'I'), ('C-u I',)) + self.add_action_and_bindings(HexRead('long', 'l'), ('C-u l',)) + self.add_action_and_bindings(HexRead('ulong', 'L'), ('C-u L',)) + self.add_action_and_bindings(HexRead('float', 'f'), ('C-u f',)) + self.add_action_and_bindings(HexRead('double', 'd'), ('C-u d',)) + self.add_action_and_bindings(HexReadAligned('int', 'i'), ('C-c i',)) self.add_action_and_bindings(HexReadAligned('uint', 'I'), ('C-c I',)) self.add_action_and_bindings(HexReadAligned('long', 'l'), ('C-c l',)) self.add_action_and_bindings(HexReadAligned('ulong', 'L'), ('C-c L',)) self.add_action_and_bindings(HexReadAligned('float', 'f'), ('C-c f',)) self.add_action_and_bindings(HexReadAligned('double', 'd'), ('C-c d',)) - self.add_action(FindStrings()) - self.add_action(WhichWord()) + + self.add_action_and_bindings(ShowAddress(), ('C-c a',)) + self.add_action_and_bindings(GotoAddress(), ('C-c M-g',)) # create all the insert actions for the basic text input for c in string.letters + string.digits + string.punctuation: @@ -121,6 +129,17 @@ class Hex(mode.Fundamental): else: return ((0, s, self.cgreen),) + def read_data(self, cy, ix, fmt, size): + b = self.window.buffer + s = b.rawdata[cy][ix:] + if len(s) < size: + if cy < len(b.rawdata) - 1: + s += b.rawdata[cy + 1] + else: + return None + s = s[:size] + return struct.unpack(fmt, s)[0] + class HexForward(Method): def _execute(self, w, **vargs): w.forward() @@ -156,7 +175,33 @@ class HexEndOfLine(Method): if w.cursor_char() == '\n': w.backward() -class HexReadAligned(Method): +class HexRead(Method): + _is_method = False + def __init__(self, type_, fmt): + self.name = 'hex-read-%s' % type_.lower() + self.type_ = type_ + self.fmt = fmt + self.size = struct.calcsize(fmt) + self.args = [] + self.help = "Read %r from address in the current buffer." % self.type_ + def _get_ix(self, b, cy, cx): + ix = b.cursorx_to_datax(cy, cx) + return ix + def _execute(self, w, **vargs): + b = w.buffer + hb = w.application.methods['hex-backward'] + (cx, cy) = w.cursor.xy() + ix = self._get_ix(b, cy, cx) + addr = b.get_address(cy, 0) + ix + try: + v = w.mode.read_data(cy, ix, self.fmt, self.size) + if v is None: + w.set_error("not enough data to read %s" % self.type_) + else: + w.set_error("%s at 0x%08x: %r" % (self.type_, addr, v)) + except Exception, e: + w.set_error("%s could not be read at 0x%08x" % (self.type_, addr)) +class HexReadAligned(HexRead): _is_method = False def __init__(self, type_, fmt): self.name = 'hex-read-aligned-%s' % type_.lower() @@ -165,27 +210,10 @@ class HexReadAligned(Method): self.size = struct.calcsize(fmt) self.args = [] self.help = "Read %r from word-aligned address in the current buffer." % self.type_ - def _execute(self, w, **vargs): - b = w.buffer - hb = w.application.methods['hex-backward'] - (cx, cy) = w.cursor.xy() + def _get_ix(self, b, cy, cx): ix = b.cursorx_to_datax(cy, cx) ix -= ix % b.wordsize - s = b.rawdata[cy][ix:] - if len(s) < self.size: - if cy < len(b.rawdata) - 1: - s += b.rawdata[cy + 1] - else: - w.set_error("not enough data to read %s" % self.type_) - return - s = s[:self.size] - try: - v = struct.unpack(self.fmt, s)[0] - addr = w.mode.get_address(cy, 0) + ix - w.set_error("%s at 0x%08x: %r" % (self.type_, addr, v)) - except: - raise - w.set_error("%s could not be read" % self.type_) + return ix class HexOverwriteChar(Method): _is_method = False @@ -200,59 +228,25 @@ class HexOverwriteChar(Method): while w.cursor_char().isspace() and w.cursor < end: w.forward() -class GotoWord(Method): +class GotoAddress(Method): '''Jump to the specified line number''' - args = [Argument("wordno", type=type(0), prompt="Goto word: ")] + args = [Argument("address", type=type(0), prompt="Goto address: ")] def _execute(self, w, **vargs): - n = vargs["wordno"] - if n < 0: - w.set_error("Negative word counts not supported.") - try: - x = (n % w.buffer.numwords) * (w.buffer.wordsize + 1) - y = n / w.buffer.numwords - p = Point(x, y) - w.goto(p) - except: - w.goto_end() - -class WhichWord(Method): - '''Show the current word number''' + b = w.buffer + addr = vargs["address"] + if addr < 0: + w.set_error("Negative address not supported.") + ix = addr % (b.groupsize * b.numgroups) + cx = w.buffer.datax_to_cursorx(ix) + cy = addr // (b.groupsize * b.numgroups) + w.goto(Point(cx, cy)) + w.set_error("Goto 0x%08x (%r, %r)" % (addr, cx, cy)) +class ShowAddress(Method): + '''Show the cursor's address in the current buffer''' def _execute(self, w, **vargs): - cursor = w.logical_cursor() - n = cursor.y * w.buffer.numwords - n += cursor.x / (w.buffer.wordsize + 1) - w.set_error("Currently in word %s (%s)" % (hex(n), n)) - -class FindStrings(Method): - def _execute(self, w, **vargs): - newlines = [] - lastline = '' - i = 0 - for line in w.buffer.lines: - lastc = None - newline = "" - for c in line: - if c not in '0123456789abcdefABCDEF': - lastc = None - elif lastc is None: - lastc = c - else: - char = chr(int(lastc + c, 16)) - lastc = None - if char in string.whitespace: - newline += ' ' - elif char in string.letters + string.digits + string.punctuation: - newline += char - else: - newline += '.' - if lastc is not None: - newline += '.' - if i == 3: - newlines.append(lastline) - lastline = '' - else: - lastline += newline - i = (i + 1) % 4 - w.application.data_buffer("*Strings*", '\n'.join(newlines), switch_to=True) + (cx, cy) = w.cursor.xy() + ix = w.buffer.cursorx_to_datax(cy, cx) + addr = w.buffer.get_address(cy, ix) + w.set_error("Cursor's address is 0x%08x" % addr) install = Hex.install