parent
50cc5a4bc7
commit
9fd4ae328b
|
@ -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)
|
||||
|
|
142
mode/hex.py
142
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
|
||||
|
|
Loading…
Reference in New Issue