Class: PDF::Reader::ValidatingReceiver

Inherits:
Object
  • Object
show all
Defined in:
lib/pdf/reader/validating_receiver.rb

Overview

Page#walk will execute the content stream of a page, calling methods on a receiver class provided by the user. Each operator has a specific set of parameters it expects, and we wrap the users receiver class in this one to verify the PDF uses valid parameters.

Without these checks, users can’t be confident about the number of parameters they’ll receive for an operator, or what the type of those parameters will be. Everyone ends up building their own type safety guard clauses and it’s tedious.

Not all operators have type safety implemented yet, but we can expand the number over time.

Instance Method Summary collapse

Constructor Details

#initialize(wrapped) ⇒ ValidatingReceiver

Returns a new instance of ValidatingReceiver.



19
20
21
# File 'lib/pdf/reader/validating_receiver.rb', line 19

def initialize(wrapped)
  @wrapped = wrapped
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(methodname, *args) ⇒ Object



251
252
253
# File 'lib/pdf/reader/validating_receiver.rb', line 251

def method_missing(methodname, *args)
  @wrapped.send(methodname, *args)
end

Instance Method Details

#begin_inline_image(*args) ⇒ Object

Inline Image Operators



224
225
226
# File 'lib/pdf/reader/validating_receiver.rb', line 224

def begin_inline_image(*args)
  call_wrapped(:begin_inline_image)
end

#begin_inline_image_data(*args) ⇒ Object



228
229
230
231
232
# File 'lib/pdf/reader/validating_receiver.rb', line 228

def begin_inline_image_data(*args)
  # We can't use call_wrapped() here because sorbet won't allow splat args with a dynamic
  # number of elements
  @wrapped.begin_inline_image_data(*args) if @wrapped.respond_to?(:begin_inline_image_data)
end

#begin_text_object(*args) ⇒ Object

Text Object Operators



59
60
61
# File 'lib/pdf/reader/validating_receiver.rb', line 59

def begin_text_object(*args)
  call_wrapped(:begin_text_object)
end

#concatenate_matrix(*args) ⇒ Object

Matrix Operators



42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/pdf/reader/validating_receiver.rb', line 42

def concatenate_matrix(*args)
  a, b, c, d, e, f = *args
  call_wrapped(
    :concatenate_matrix,
    TypeCheck.cast_to_numeric!(a),
    TypeCheck.cast_to_numeric!(b),
    TypeCheck.cast_to_numeric!(c),
    TypeCheck.cast_to_numeric!(d),
    TypeCheck.cast_to_numeric!(e),
    TypeCheck.cast_to_numeric!(f),
  )
end

#end_inline_image(*args) ⇒ Object



234
235
236
237
238
239
240
241
# File 'lib/pdf/reader/validating_receiver.rb', line 234

def end_inline_image(*args)
  data, _ = *args

  call_wrapped(
    :end_inline_image,
    TypeCheck.cast_to_string!(data)
  )
end

#end_text_object(*args) ⇒ Object



63
64
65
# File 'lib/pdf/reader/validating_receiver.rb', line 63

def end_text_object(*args)
  call_wrapped(:end_text_object)
end

#invoke_xobject(*args) ⇒ Object

Form XObject Operators



211
212
213
214
215
216
217
218
# File 'lib/pdf/reader/validating_receiver.rb', line 211

def invoke_xobject(*args)
  label, _ = *args

  call_wrapped(
    :invoke_xobject,
    TypeCheck.cast_to_symbol(label)
  )
end

#move_text_position(*args) ⇒ Object

Text Positioning Operators



131
132
133
134
135
136
137
138
# File 'lib/pdf/reader/validating_receiver.rb', line 131

def move_text_position(*args) # Td
  x, y, _ = *args
  call_wrapped(
    :move_text_position,
    TypeCheck.cast_to_numeric!(x),
    TypeCheck.cast_to_numeric!(y)
  )
end

#move_text_position_and_set_leading(*args) ⇒ Object

TD



140
141
142
143
144
145
146
147
# File 'lib/pdf/reader/validating_receiver.rb', line 140

def move_text_position_and_set_leading(*args) # TD
  x, y, _ = *args
  call_wrapped(
    :move_text_position_and_set_leading,
    TypeCheck.cast_to_numeric!(x),
    TypeCheck.cast_to_numeric!(y)
  )
end

#move_to_next_line_and_show_text(*args) ⇒ Object



189
190
191
192
193
194
195
# File 'lib/pdf/reader/validating_receiver.rb', line 189

def move_to_next_line_and_show_text(*args) # '
  string, _ = *args
  call_wrapped(
    :move_to_next_line_and_show_text,
    TypeCheck.cast_to_string!(string)
  )
end

#move_to_start_of_next_line(*args) ⇒ Object

T*



162
163
164
# File 'lib/pdf/reader/validating_receiver.rb', line 162

def move_to_start_of_next_line(*args) # T*
  call_wrapped(:move_to_start_of_next_line)
end

#page=(page) ⇒ Object



23
24
25
# File 'lib/pdf/reader/validating_receiver.rb', line 23

def page=(page)
  call_wrapped(:page=, page)
end

#respond_to?(meth) ⇒ Boolean

Final safety net for any operators that don’t have type checking enabled yet

Returns:

  • (Boolean)


247
248
249
# File 'lib/pdf/reader/validating_receiver.rb', line 247

def respond_to?(meth)
  @wrapped.respond_to?(meth)
end

#restore_graphics_state(*args) ⇒ Object



34
35
36
# File 'lib/pdf/reader/validating_receiver.rb', line 34

def restore_graphics_state(*args)
  call_wrapped(:restore_graphics_state)
end

#save_graphics_state(*args) ⇒ Object

Graphics State Operators



30
31
32
# File 'lib/pdf/reader/validating_receiver.rb', line 30

def save_graphics_state(*args)
  call_wrapped(:save_graphics_state)
end

#set_character_spacing(*args) ⇒ Object

Text State Operators



70
71
72
73
74
75
76
# File 'lib/pdf/reader/validating_receiver.rb', line 70

def set_character_spacing(*args)
  char_spacing, _ = *args
  call_wrapped(
    :set_character_spacing,
    TypeCheck.cast_to_numeric!(char_spacing)
  )
end

#set_horizontal_text_scaling(*args) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/pdf/reader/validating_receiver.rb', line 78

def set_horizontal_text_scaling(*args)
  h_scaling, _ = *args
  call_wrapped(
    :set_horizontal_text_scaling,
    TypeCheck.cast_to_numeric!(h_scaling)
  )
end

#set_spacing_next_line_show_text(*args) ⇒ Object



197
198
199
200
201
202
203
204
205
# File 'lib/pdf/reader/validating_receiver.rb', line 197

def set_spacing_next_line_show_text(*args) # "
  aw, ac, string = *args
  call_wrapped(
    :set_spacing_next_line_show_text,
    TypeCheck.cast_to_numeric!(aw),
    TypeCheck.cast_to_numeric!(ac),
    TypeCheck.cast_to_string!(string)
  )
end

#set_text_font_and_size(*args) ⇒ Object



86
87
88
89
90
91
92
93
# File 'lib/pdf/reader/validating_receiver.rb', line 86

def set_text_font_and_size(*args)
  label, size, _ = *args
  call_wrapped(
    :set_text_font_and_size,
    TypeCheck.cast_to_symbol(label),
    TypeCheck.cast_to_numeric!(size)
  )
end

#set_text_leading(*args) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/pdf/reader/validating_receiver.rb', line 95

def set_text_leading(*args)
  leading, _ = *args
  call_wrapped(
    :set_text_leading,
    TypeCheck.cast_to_numeric!(leading)
  )
end

#set_text_matrix_and_text_line_matrix(*args) ⇒ Object

Tm



149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/pdf/reader/validating_receiver.rb', line 149

def set_text_matrix_and_text_line_matrix(*args) # Tm
  a, b, c, d, e, f = *args
  call_wrapped(
    :set_text_matrix_and_text_line_matrix,
    TypeCheck.cast_to_numeric!(a),
    TypeCheck.cast_to_numeric!(b),
    TypeCheck.cast_to_numeric!(c),
    TypeCheck.cast_to_numeric!(d),
    TypeCheck.cast_to_numeric!(e),
    TypeCheck.cast_to_numeric!(f),
  )
end

#set_text_rendering_mode(*args) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/pdf/reader/validating_receiver.rb', line 103

def set_text_rendering_mode(*args)
  mode, _ = *args
  call_wrapped(
    :set_text_rendering_mode,
    TypeCheck.cast_to_numeric!(mode)
  )
end

#set_text_rise(*args) ⇒ Object



111
112
113
114
115
116
117
# File 'lib/pdf/reader/validating_receiver.rb', line 111

def set_text_rise(*args)
  rise, _ = *args
  call_wrapped(
    :set_text_rise,
    TypeCheck.cast_to_numeric!(rise)
  )
end

#set_word_spacing(*args) ⇒ Object



119
120
121
122
123
124
125
# File 'lib/pdf/reader/validating_receiver.rb', line 119

def set_word_spacing(*args)
  word_spacing, _ = *args
  call_wrapped(
    :set_word_spacing,
    TypeCheck.cast_to_numeric!(word_spacing)
  )
end

#show_text(*args) ⇒ Object

Text Showing Operators



169
170
171
172
173
174
175
# File 'lib/pdf/reader/validating_receiver.rb', line 169

def show_text(*args) # Tj (AWAY)
  string, _ = *args
  call_wrapped(
    :show_text,
    TypeCheck.cast_to_string!(string)
  )
end

#show_text_with_positioning(*args) ⇒ Object

TJ [(A) 120 (WA) 20 (Y)]



177
178
179
180
181
182
183
184
185
186
187
# File 'lib/pdf/reader/validating_receiver.rb', line 177

def show_text_with_positioning(*args) # TJ [(A) 120 (WA) 20 (Y)]
  params, _ = *args
  unless params.is_a?(Array)
    raise MalformedPDFError, "TJ operator expects a single Array argument"
  end

  call_wrapped(
    :show_text_with_positioning,
    params
  )
end