Skip to content

Commit 6456d86

Browse files
author
Steve Canny
committed
img: add _MarkerParser.from_stream()
1 parent 96774c5 commit 6456d86

File tree

2 files changed

+63
-4
lines changed

2 files changed

+63
-4
lines changed

docx/image/jpeg.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from __future__ import absolute_import, division, print_function
99

1010
from .constants import JPEG_MARKER_CODE
11+
from .helpers import BIG_ENDIAN, StreamReader
1112
from .image import Image
1213

1314

@@ -104,23 +105,41 @@ class _MarkerParser(object):
104105
Service class that knows how to parse a JFIF stream and iterate over its
105106
markers.
106107
"""
108+
def __init__(self, stream_reader):
109+
super(_MarkerParser, self).__init__()
110+
self._stream = stream_reader
111+
107112
@classmethod
108113
def from_stream(cls, stream):
109114
"""
110115
Return a |_MarkerParser| instance to parse JFIF markers from
111116
*stream*.
112117
"""
113-
raise NotImplementedError
118+
stream_reader = StreamReader(stream, BIG_ENDIAN)
119+
return cls(stream_reader)
114120

115121
def iter_markers(self):
116122
"""
117-
Generate a (marker_code, segment_offset) 3-tuple for each marker in
118-
the JPEG byte stream in *stream*, in the order they occur in the
119-
stream.
123+
Generate a (marker_code, segment_offset) 2-tuple for each marker in
124+
the JPEG *stream*, in the order they occur in the stream.
120125
"""
121126
raise NotImplementedError
122127

123128

129+
class _MarkerFinder(object):
130+
"""
131+
Service class that knows how to find the next JFIF marker in a stream.
132+
"""
133+
134+
135+
def _MarkerFactory(marker_code, stream, offset):
136+
"""
137+
Return |_Marker| or subclass instance appropriate for marker at *offset*
138+
in *stream* having *marker_code*.
139+
"""
140+
raise NotImplementedError
141+
142+
124143
class _Marker(object):
125144
"""
126145
Base class for JFIF marker classes. Represents a marker and its segment

tests/image/test_jpeg.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from docx.compat import BytesIO
1212
from docx.image.constants import JPEG_MARKER_CODE
13+
from docx.image.helpers import BIG_ENDIAN, StreamReader
1314
from docx.image.jpeg import (
1415
_App0Marker, Jfif, _JfifMarkers, _Marker, _MarkerParser, _SofMarker
1516
)
@@ -145,3 +146,42 @@ def sos_(self, request):
145146
@pytest.fixture
146147
def stream_(self, request):
147148
return instance_mock(request, BytesIO)
149+
150+
151+
class Describe_MarkerParser(object):
152+
153+
def it_can_construct_from_a_jfif_stream(self, from_stream_fixture):
154+
stream_, StreamReader_, _MarkerParser__init_, stream_reader_ = (
155+
from_stream_fixture
156+
)
157+
marker_parser = _MarkerParser.from_stream(stream_)
158+
StreamReader_.assert_called_once_with(stream_, BIG_ENDIAN)
159+
_MarkerParser__init_.assert_called_once_with(stream_reader_)
160+
assert isinstance(marker_parser, _MarkerParser)
161+
162+
# fixtures -------------------------------------------------------
163+
164+
@pytest.fixture
165+
def from_stream_fixture(
166+
self, stream_, StreamReader_, _MarkerParser__init_,
167+
stream_reader_):
168+
return stream_, StreamReader_, _MarkerParser__init_, stream_reader_
169+
170+
@pytest.fixture
171+
def _MarkerParser__init_(self, request):
172+
return initializer_mock(request, _MarkerParser)
173+
174+
@pytest.fixture
175+
def stream_(self, request):
176+
return instance_mock(request, BytesIO)
177+
178+
@pytest.fixture
179+
def StreamReader_(self, request, stream_reader_):
180+
return class_mock(
181+
request, 'docx.image.jpeg.StreamReader',
182+
return_value=stream_reader_
183+
)
184+
185+
@pytest.fixture
186+
def stream_reader_(self, request):
187+
return instance_mock(request, StreamReader)

0 commit comments

Comments
 (0)