Skip to content

Commit 2c6d96a

Browse files
author
Steve Canny
committed
img: add StreamReader.read_long()
1 parent b5da364 commit 2c6d96a

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

docx/image/helpers.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ def __init__(self, stream, byte_order, base_offset=0):
2525
)
2626
self._base_offset = base_offset
2727

28+
def read_long(self, base=None, offset=0):
29+
"""
30+
Return the int value of the four bytes at the file position defined by
31+
self._base_offset + *base* + *offset*. If *base* is None, the long is
32+
read from the current position in the stream. The endian setting of
33+
this instance is used to interpret the byte layout of the long.
34+
"""
35+
fmt = '<L' if self._byte_order is LITTLE_ENDIAN else '>L'
36+
return self._read_int(fmt, base, offset)
37+
2838
def read_str(self, char_count, base, offset=0):
2939
"""
3040
Return a string containing the *char_count* bytes at the file
@@ -49,6 +59,12 @@ def _read_bytes(self, byte_count, base, offset):
4959
raise UnexpectedEndOfFileError
5060
return bytes_
5161

62+
def _read_int(self, fmt, base, offset):
63+
struct = Struct(fmt)
64+
if base is None:
65+
base = self._stream.tell() - self._base_offset
66+
return self._unpack_item(struct, base, offset)
67+
5268
def _unpack_item(self, struct, base, offset):
5369
bytes_ = self._read_bytes(struct.size, base, offset)
5470
return struct.unpack(bytes_)[0]

tests/image/test_helpers.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from docx.compat import BytesIO
1212
from docx.image.exceptions import UnexpectedEndOfFileError
13-
from docx.image.helpers import BIG_ENDIAN, StreamReader
13+
from docx.image.helpers import BIG_ENDIAN, LITTLE_ENDIAN, StreamReader
1414

1515

1616
class DescribeStreamReader(object):
@@ -26,8 +26,23 @@ def it_raises_on_unexpected_EOF(self, read_str_fixture):
2626
with pytest.raises(UnexpectedEndOfFileError):
2727
stream_rdr.read_str(9, 2)
2828

29+
def it_can_read_a_long(self, read_long_fixture):
30+
stream_rdr, offset, expected_int = read_long_fixture
31+
l = stream_rdr.read_long(offset)
32+
assert l == expected_int
33+
2934
# fixtures -------------------------------------------------------
3035

36+
@pytest.fixture(params=[
37+
(BIG_ENDIAN, b'\xBE\x00\x00\x00\x2A\xEF', 1, 42),
38+
(LITTLE_ENDIAN, b'\xBE\xEF\x2A\x00\x00\x00', 2, 42),
39+
])
40+
def read_long_fixture(self, request):
41+
byte_order, bytes_, offset, expected_int = request.param
42+
stream = BytesIO(bytes_)
43+
stream_rdr = StreamReader(stream, byte_order)
44+
return stream_rdr, offset, expected_int
45+
3146
@pytest.fixture
3247
def read_str_fixture(self):
3348
stream = BytesIO(b'\x01\x02foobar\x03\x04')

0 commit comments

Comments
 (0)