Skip to content

Commit

Permalink
Pointer updated, added stream optional parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
arekbulski committed Apr 8, 2018
1 parent 8404229 commit 0223997
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 4 deletions.
10 changes: 7 additions & 3 deletions construct/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -4044,6 +4044,7 @@ class Pointer(Subconstruct):
:param offset: integer or context lambda, positive or negative
:param subcon: Construct instance
:param stream: None to use original stream (default), or context lambda to provide a different stream
:raises StreamError: requested reading negative amount, could not read enough bytes, requested writing different amount than actual data, or could not write all bytes
:raises StreamError: stream is not seekable and tellable
Expand All @@ -4059,20 +4060,23 @@ class Pointer(Subconstruct):
b'\x00\x00\x00\x00\x00\x00\x00\x00Z'
"""

def __init__(self, offset, subcon):
def __init__(self, offset, subcon, stream=None):
super(Pointer, self).__init__(subcon)
self.offset = offset
self.stream = stream

def _parse(self, stream, context, path):
offset = self.offset(context) if callable(self.offset) else self.offset
offset = evaluate(self.offset, context)
stream = evaluate(self.stream, context) or stream
fallback = stream_tell(stream)
stream_seek(stream, offset, 2 if offset < 0 else 0)
obj = self.subcon._parsereport(stream, context, path)
stream_seek(stream, fallback)
return obj

def _build(self, obj, stream, context, path):
offset = self.offset(context) if callable(self.offset) else self.offset
offset = evaluate(self.offset, context)
stream = evaluate(self.stream, context) or stream
fallback = stream_tell(stream)
stream_seek(stream, offset, 2 if offset < 0 else 0)
buildret = self.subcon._build(obj, stream, context, path)
Expand Down
2 changes: 1 addition & 1 deletion docs/transition29.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ EmbeddedSwitch added, in Conditional (`see tutorial page <https://construct.read

StopIf raises `StopFieldError` instead of `StopIteration` (`see API page <https://construct.readthedocs.io/en/latest/api/conditional.html#construct.StopIf>`_)

Pointer changed size to 0, can be parsed lazily
Pointer changed size to 0, can be parsed lazily, can also select a stream from context entry

PrefixedArray parameter `lengthfield` renamed to `countfield` (`see API page <https://construct.readthedocs.io/en/latest/api/tunneling.html#construct.PrefixedArray>`_)

Expand Down
6 changes: 6 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,12 @@ def test_pointer():
common(Pointer(2, Byte), b"\x00\x00\x07", 7, 0)
common(Pointer(lambda ctx: 2, Byte), b"\x00\x00\x07", 7, 0)

d = Struct(
'inner' / Struct(),
'x' / Pointer(0, Byte, stream=this.inner._io),
)
d.parse(bytes(20)) == 0

def test_peek():
d = Peek(Int8ub)
assert d.parse(b"\x01") == 1
Expand Down

0 comments on commit 0223997

Please sign in to comment.