Skip to content

Commit 3d3415e

Browse files
author
Steve Canny
committed
img: add _IfdParser.iter_entries()
1 parent e72d14d commit 3d3415e

File tree

2 files changed

+64
-2
lines changed

2 files changed

+64
-2
lines changed

docx/image/tiff.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,25 @@ def iter_entries(self):
133133
Generate an |_IfdEntry| instance corresponding to each entry in the
134134
directory.
135135
"""
136-
raise NotImplementedError
136+
for idx in range(self._entry_count):
137+
dir_entry_offset = self._offset + 2 + (idx*12)
138+
ifd_entry = _IfdEntryFactory(self._stream_rdr, dir_entry_offset)
139+
yield ifd_entry
140+
141+
@property
142+
def _entry_count(self):
143+
"""
144+
The count of directory entries, read from the top of the IFD header
145+
"""
146+
return self._stream_rdr.read_short(self._offset)
147+
148+
149+
def _IfdEntryFactory(stream_rdr, offset):
150+
"""
151+
Return an |_IfdEntry| subclass instance containing the value of the
152+
directory entry at *offset* in *stream_rdr*.
153+
"""
154+
raise NotImplementedError
137155

138156

139157
class _IfdEntry(object):

tests/image/test_tiff.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@
88

99
import pytest
1010

11+
from mock import call
12+
1113
from docx.compat import BytesIO
1214
from docx.image.helpers import BIG_ENDIAN, LITTLE_ENDIAN, StreamReader
1315
from docx.image.tiff import (
1416
_IfdEntries, _IfdEntry, _IfdParser, Tiff, _TiffParser
1517
)
1618

1719
from ..unitutil import (
18-
initializer_mock, class_mock, instance_mock, method_mock
20+
function_mock, class_mock, initializer_mock, instance_mock, method_mock
1921
)
2022

2123

@@ -207,3 +209,45 @@ def offset_(self, request):
207209
@pytest.fixture
208210
def stream_(self, request):
209211
return instance_mock(request, BytesIO)
212+
213+
214+
class Describe_IfdParser(object):
215+
216+
def it_can_iterate_through_the_directory_entries_in_an_IFD(
217+
self, iter_fixture):
218+
(ifd_parser, _IfdEntryFactory_, stream_rdr, offsets,
219+
expected_entries) = iter_fixture
220+
entries = [e for e in ifd_parser.iter_entries()]
221+
assert _IfdEntryFactory_.call_args_list == [
222+
call(stream_rdr, offsets[0]),
223+
call(stream_rdr, offsets[1]),
224+
]
225+
assert entries == expected_entries
226+
227+
# fixtures -------------------------------------------------------
228+
229+
@pytest.fixture
230+
def ifd_entry_(self, request):
231+
return instance_mock(request, _IfdEntry, tag=1, value=42)
232+
233+
@pytest.fixture
234+
def ifd_entry_2_(self, request):
235+
return instance_mock(request, _IfdEntry, tag=2, value=24)
236+
237+
@pytest.fixture
238+
def _IfdEntryFactory_(self, request, ifd_entry_, ifd_entry_2_):
239+
return function_mock(
240+
request, 'docx.image.tiff._IfdEntryFactory',
241+
side_effect=[ifd_entry_, ifd_entry_2_]
242+
)
243+
244+
@pytest.fixture
245+
def iter_fixture(self, _IfdEntryFactory_, ifd_entry_, ifd_entry_2_):
246+
stream_rdr = StreamReader(BytesIO(b'\x00\x02'), BIG_ENDIAN)
247+
offsets = [2, 14]
248+
ifd_parser = _IfdParser(stream_rdr, offset=0)
249+
expected_entries = [ifd_entry_, ifd_entry_2_]
250+
return (
251+
ifd_parser, _IfdEntryFactory_, stream_rdr, offsets,
252+
expected_entries
253+
)

0 commit comments

Comments
 (0)