Class: HexaPDF::Stream

Inherits:
Dictionary show all
Defined in:
lib/hexapdf/stream.rb,
lib/hexapdf/dictionary.rb

Overview

:nodoc: Forward declaration of Stream to circumvent circular require problem

Constant Summary

Constants included from DictionaryFields

DictionaryFields::Boolean, DictionaryFields::PDFByteString, DictionaryFields::PDFDate

Instance Attribute Summary

Attributes inherited from Object

#data, #document, #must_be_indirect

Instance Method Summary collapse

Methods inherited from Dictionary

#[], #[]=, define_field, define_type, #delete, #each, each_field, #empty?, field, #key?, #to_hash, type, #type

Methods inherited from Object

#<=>, #==, #cache, #cached?, #clear_cache, deep_copy, #deep_copy, #document?, #eql?, field, #gen, #gen=, #hash, #indirect?, #initialize, #inspect, make_direct, #null?, #oid, #oid=, #type, #validate, #value, #value=

Constructor Details

This class inherits a constructor from HexaPDF::Object

Instance Method Details

#must_be_indirect?Boolean

Stream objects must always be indirect.

Returns:



151
152
153
# File 'lib/hexapdf/stream.rb', line 151

def must_be_indirect?
  true
end

#raw_streamObject

Returns the raw stream object.

The returned value can be of many different types (see #stream=). For working with the decoded stream contents use #stream.



181
182
183
# File 'lib/hexapdf/stream.rb', line 181

def raw_stream
  data.stream
end

#set_filter(filter, decode_parms = nil) ⇒ Object

Sets the filters that should be used for encoding the stream.

The arguments filter as well as decode_parms can either be a single items or arrays.

The filters have to be specified in the *decoding order*! For example, if the filters would be [:A85, :Fl], the stream would first be encoded with the Flate and then with the ASCII85 filter.



247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/hexapdf/stream.rb', line 247

def set_filter(filter, decode_parms = nil)
  if filter.nil? || (filter.kind_of?(Array) && filter.empty?)
    delete(:Filter)
  else
    self[:Filter] = filter
  end
  if decode_parms.nil? || (decode_parms.kind_of?(Array) && decode_parms.empty?) ||
      !key?(:Filter)
    delete(:DecodeParms)
  else
    self[:DecodeParms] = decode_parms
  end
end

#streamObject

Returns the (possibly decoded) stream data as string.

Note that modifications done to the returned string are not reflected in the Stream object itself. The modified string must explicitly be assigned via #stream= to take effect.



169
170
171
172
173
174
175
# File 'lib/hexapdf/stream.rb', line 169

def stream
  if data.stream.kind_of?(String)
    data.stream.dup
  else
    HexaPDF::Filter.string_from_source(stream_decoder)
  end
end

#stream=(stream) ⇒ Object

Assigns a new stream data object.

The stream argument can be a HexaPDF::StreamData object, a String object or nil.

If stream is nil, an empty binary string is used instead.



160
161
162
163
# File 'lib/hexapdf/stream.rb', line 160

def stream=(stream)
  data.stream = stream
  after_data_change
end

#stream_decoderObject

Returns the decoder Fiber for the stream data.

See the Filter module for more information on how to work with the fiber.



197
198
199
200
201
202
203
204
205
206
207
# File 'lib/hexapdf/stream.rb', line 197

def stream_decoder
  source = stream_source

  if data.stream.kind_of?(StreamData)
    data.stream.filter.zip(data.stream.decode_parms) do |filter, decode_parms|
      source = filter_for_name(filter).decoder(source, decode_parms)
    end
  end

  source
end

#stream_encoder(source = stream_source) ⇒ Object

:call-seq:

stream.stream_encoder

Returns the encoder Fiber for the stream data.

See the Filter module for more information on how to work with the fiber.



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/hexapdf/stream.rb', line 215

def stream_encoder(source = stream_source)
  encoder_data = [document.unwrap(self[:Filter])].flatten.
    zip([document.unwrap(self[:DecodeParms])].flatten).
    delete_if {|f, _| f.nil? }

  if data.stream.kind_of?(StreamData)
    decoder_data = data.stream.filter.zip(data.stream.decode_parms)

    while !decoder_data.empty? && !encoder_data.empty? && decoder_data.last == encoder_data.last
      decoder_data.pop
      encoder_data.pop
    end

    decoder_data.each do |filter, decode_parms|
      source = filter_for_name(filter).decoder(source, decode_parms)
    end
  end

  encoder_data.reverse!.each do |filter, decode_parms|
    source = filter_for_name(filter).encoder(source, decode_parms)
  end

  source
end

#stream_sourceObject

Returns the Fiber representing the unprocessed content of the stream.



186
187
188
189
190
191
192
# File 'lib/hexapdf/stream.rb', line 186

def stream_source
  if data.stream.kind_of?(String)
    HexaPDF::Filter.source_from_string(data.stream)
  else
    data.stream.fiber(config['io.chunk_size'])
  end
end