class HexaPDF::Stream

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

def after_data_change

Makes sure that the stream data is either a String or a HexaPDF::StreamData object.
def after_data_change
  super
  data.stream ||= ''.b
  unless data.stream.kind_of?(StreamData) || data.stream.kind_of?(String)
    raise ArgumentError, "Object of class #{data.stream.class} cannot be used as stream value"
  end
end

def filter_for_name(filter_name)

See: HexaPDF::Filter

Returns the filter object that corresponds to the given filter name.
def filter_for_name(filter_name)
  config.constantize('filter.map', filter_name) do
    raise HexaPDF::Error, "Unknown stream filter '#{filter_name}' encountered"
  end
end

def must_be_indirect?

Stream objects must always be indirect.
def must_be_indirect?
  true
end

def perform_validation

Validates the /Filter entry so that it contains only long-name filter names.
def perform_validation
  super
  if value[:Filter].kind_of?(Symbol) && FILTER_MAP.key?(value[:Filter])
    yield("A stream's /Filter entry may only use long-form filter names", true)
    value[:Filter] = FILTER_MAP[value[:Filter]]
  elsif value[:Filter].kind_of?(Array)
    value[:Filter].map! do |filter|
      next filter unless FILTER_MAP.key?(filter)
      yield("A stream's /Filter entry may only use long-form filter names", true)
      FILTER_MAP[filter]
    end
  end
end

def raw_stream

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

Returns the raw stream object.
def raw_stream
  data.stream
end

def set_filter(filter, decode_parms = nil)

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

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

Sets the filters that should be used for encoding the stream.
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

def stream

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

Returns the (possibly decoded) stream data as string.
def stream
  if data.stream.kind_of?(String)
    data.stream.dup
  else
    HexaPDF::Filter.string_from_source(stream_decoder)
  end
end

def stream=(stream)

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

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

Assigns a new stream data object.
def stream=(stream)
  data.stream = stream
  after_data_change
end

def stream_decoder

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

Returns the decoder Fiber for the stream data.
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

def stream_encoder(source = stream_source)

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

Returns the encoder Fiber for the stream data.

stream.stream_encoder
:call-seq:
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

def stream_source

Returns the Fiber representing the unprocessed content of the stream.
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