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_h, type, #type

Methods inherited from Object

#<=>, #==, #cache, #cached?, #clear_cache, deep_copy, #deep_copy, #document?, #eql?, #gen, #gen=, #hash, #indirect?, #initialize, #inspect, #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:



149
150
151
# File 'lib/hexapdf/stream.rb', line 149

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.



179
180
181
# File 'lib/hexapdf/stream.rb', line 179

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.



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

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.



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

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.



158
159
160
161
# File 'lib/hexapdf/stream.rb', line 158

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.



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

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.



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

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.



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

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