Compare commits

...

4 Commits

5 changed files with 33 additions and 23 deletions

View File

@ -121,13 +121,17 @@ class Context:
raise Error(self, ValueError('could not enter segment {}: could not calculate offset'.format(segment)))
with seeking(stream.root, pos, reference) as s, stream.wrapped(s) as f:
self.segment_path.append(segment)
yield f
self.segment_path.pop()
segment.pos = f.tell()
try:
yield f
segment.pos = f.tell()
finally:
self.segment_path.pop()
else:
self.segment_path.append(segment)
yield stream
self.segment_path.pop()
try:
yield stream
finally:
self.segment_path.pop()
def segment_offset(self, segment: Segment) -> O[Pos]:
size: Pos = 0
@ -142,7 +146,7 @@ class Context:
return size
def segment_size(self, segment: Segment) -> O[Pos]:
sizes = self.sizeof(self.root, self.value)
sizes = Context(self.root, self.value, params=self.params, reset=False).sizeof(self.root, self.value)
return sizes.get(segment, None)
def format_path(self) -> str:

View File

@ -20,6 +20,7 @@ import sx
from .core import parse, to_type
from .core.base import Params, Type
from .core.io import Stream, Pos, to_stream
from .core.meta import Generic, Wrapper
from .core.util import format_value
@ -158,7 +159,7 @@ class StreamASCIIView(StreamView):
r.append('\n')
this_end = min(align_down_to(pos + self.stream_window.line, self.stream_window.line), end)
r.append((
''.join(chr(x) if chr(x).isprintable() else '.' for x in self.stream_window.buf[pos:this_end]),
''.join(chr(x) if chr(x).isprintable() and x < 127 else '.' for x in self.stream_window.buf[pos:this_end]),
data_style,
))
pos = this_end
@ -208,11 +209,10 @@ class TypeView(Widget):
return Panel(Text(format_value(to_type(self.type), str)), title='type')
class TreeNode:
__slots__ = ('parent', 'ident', 'name', 'value', 'error', 'children', 'selected', 'hidden', 'extra')
__slots__ = ('parent', 'name', 'value', 'error', 'children', 'selected', 'hidden', 'extra')
def __init__(self, parent, ident, name, value = None, error = None, children = None, extra=None) -> None:
def __init__(self, parent, name, value = None, error = None, children = None, extra=None) -> None:
self.parent = parent
self.ident = ident
self.name = name
self.value = value
self.error = error
@ -291,10 +291,13 @@ class TreeView(Widget):
r.append(' ' * (depth + d + 1) + self.depth_close + '\n')
r.append(indent)
curr_style = self.selected_style if curr.selected else (self.hidden_style if curr.hidden else self.node_style)
if curr.ident is not None:
r.append((str(curr.ident), self.hidden_style))
if curr.extra['ident'] is not None:
r.append((str(curr.extra['ident']), self.hidden_style))
r.append(': ')
r.append((curr.name, curr_style))
if curr.error is not None:
r.append(' => ')
r.append((f'{type(curr.error).__name__}: {curr.error}', self.error_style))
if curr.children:
if curr.hidden:
r.append(self.depth_hidden)
@ -303,10 +306,7 @@ class TreeView(Widget):
else:
if curr.value is not None:
r.append(' => ')
r.append((redact(str(curr.value), 64), curr_style))
if curr.error is not None:
r.append(' => ')
r.append((f'{type(curr.error).__name__}: {curr.error}', self.error_style))
r.append((redact(repr(curr.value), 64), curr_style))
r.append('\n')
prev_depth = depth
if not self.root_node.hidden and self.root_node.children and self.depth_close is not None:
@ -415,11 +415,16 @@ class SXplore(App):
name = old_node.type.__class__.__name__
for i in range(prev_depth - depth):
new_stack.pop()
new_node = TreeNode(new_stack[-1] if new_stack else None, ident, name, old_node.value, old_node.error, extra={'pos': old_node.pos, 'end': old_node.end})
new_node = TreeNode(new_stack[-1] if new_stack else None, name, old_node.value, old_node.error, extra={'ident': ident, 'pos': old_node.pos, 'end': old_node.end})
if not new_stack:
new_root = new_node
if old_node.children:
old_stack = [(depth + 1, c) for c in old_node.children] + old_stack
ns = []
for ident, c in old_node.children:
if isinstance(c.type, (Generic, Wrapper)):
_, c = c.children[0]
ns.append((depth + 1, (ident, c)))
old_stack = ns + old_stack
new_stack.append(new_node)
prev_depth = depth

View File

@ -185,7 +185,7 @@ class Terminated(G[T], Wrapper[T]):
tstream = TerminatedStream(stream, terminator, included, blocksize=self.blocksize)
value = super().parse(context, tstream)
if required and tstream._end_pos is None:
raise IOError(f'terminator {terminator} not found in stream')
raise EOFError(f'terminator {terminator} not found in stream')
return value
def dump(self, context: Context, stream: Stream, value: T) -> None:
@ -249,7 +249,7 @@ class Ref(G[T], Wrapper[T]):
def offsetof(self, context: Context, path: Sequence[PathElement], value: O[T]) -> O[Pos]:
segment = context.peek(self.segment) or context.params.segments['refs']
with context.enter_segment(segment):
return super().contextof(context, path, value)
return super().offsetof(context, path, value)
def __str__(self) -> str:
indicator = {os.SEEK_SET: '', os.SEEK_CUR: '+', os.SEEK_END: '-'}.get(self.whence, self.whence)

View File

@ -59,7 +59,7 @@ class Arr(G[T], Type[List[T]]):
for i, elem in enumerate(value):
c = to_type(child)
with context.enter(i, c):
context.dump(child, stream, elem)
context.dump(c, stream, elem)
context.put(self.count, len(value))

View File

@ -142,8 +142,9 @@ class StructType(G[T], Type[T]):
elem = getattr(value, field)
else:
elem = None
with context.enter(field, child):
size = context.sizeof(child, elem)
c = to_type(child, field)
with context.enter(field, c):
size = context.sizeof(c, elem)
sizes.append(size)
return sizes