Esempio n. 1
0
def seek_temporary(stream: IO[Any], path: str, offset: int) -> Iterator[None]:
    '''
    Context manager which seeks to the specified offset on entering,
    and seeks back to the original offset on exit
    '''
    fallback = stream_tell(stream, path)
    stream_seek(stream, offset, 0, path)
    yield
    stream_seek(stream, fallback, 0, path)
Esempio n. 2
0
    def _parse(self, stream, context, path):
        # Get Index if we are in an Array, Sequence, ...
        if hasattr(context, "_index"):
            index = context._index
        else:
            index = None

        offset_start = cs.stream_tell(stream, path)
        obj = self.subcon._parsereport(stream, context, path)  # type: ignore
        offset_end = cs.stream_tell(stream, path)

        gui_metadata = GuiMetaData(
            offset_start=offset_start,
            offset_end=offset_end,
            length=offset_end - offset_start,
            construct=self.subcon,
            index=index,
            context=context,
        )

        return add_gui_metadata(obj, gui_metadata)
Esempio n. 3
0
def get_offset_in_outer_stream(stream, context, path):
    '''
    Tries to calculate the current offset in the outermost stream by traversing the context tree.

    This is very likely to go completely wrong in many configurations;
    right now it takes streams in other contexts and the :class:`Prefixed` type into account.
    '''
    offset = stream_tell(stream, path)

    # collect offsets of enclosing streams by walking up the tree
    prev_stream = stream
    for c in iter_context_tree(context):
        curr_stream = getattr(c, '_io', None)
        if curr_stream is None:
            break

        # add to offset if stream changed
        if curr_stream is not prev_stream:
            offset += stream_tell(curr_stream, path)
        prev_stream = curr_stream

    # the Prefixed type writes the length _after_ building the subcon (which makes sense),
    #  but that also means that the current data will be written at [current offset] + [size of length field],
    #  which has to be taken into account as the stream's offset doesn't include the length field yet
    stack = inspect.stack()
    try:
        for info in stack:
            if info.function != '_build':
                continue
            local_self = info.frame.f_locals.get('self')
            if isinstance(local_self, Prefixed):
                offset += local_self.lengthfield.sizeof()
    finally:
        del stack  # just to be safe, see https://docs.python.org/3/library/inspect.html#the-interpreter-stack

    return offset
Esempio n. 4
0
def stream_tell(stream, path):
    return C.stream_tell(stream, path)
Esempio n. 5
0
 def _pad(self, stream, path):
     v = self.modulus - 1
     pos = stream_tell(stream, path)
     newpos = (pos + v) & ~v
     return newpos - pos