File: stream.rb

package info (click to toggle)
ruby-pdf-core 0.10.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 408 kB
  • sloc: ruby: 2,270; makefile: 4
file content (134 lines) | stat: -rw-r--r-- 3,023 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# frozen_string_literal: true

# prawn/core/stream.rb : Implements Stream objects
#
# Copyright February 2013, Alexander Mankuta.  All Rights Reserved.
#
# This is free software. Please see the LICENSE and COPYING files for details.

module PDF
  module Core
    # PDF Stream object
    class Stream
      # Stream filters
      # @return [PDF::Core::FilterList]
      attr_reader :filters

      # @param io [String] must be mutable
      def initialize(io = nil)
        @filtered_stream = ''
        @stream = io
        @filters = FilterList.new
      end

      # Append data to stream.
      #
      # @param io [String]
      # @return [self]
      def <<(io)
        (@stream ||= +'') << io
        @filtered_stream = nil
        self
      end

      # Set up stream to be compressed when serialized.
      #
      # @return [void]
      def compress!
        unless @filters.names.include?(:FlateDecode)
          @filtered_stream = nil
          @filters << :FlateDecode
        end
      end

      # Is this stream compressed?
      #
      # @return [Boolean]
      def compressed?
        @filters.names.include?(:FlateDecode)
      end

      # Is there any data in this stream?
      #
      # @return [Boolean]
      def empty?
        @stream.nil?
      end

      # Stream data with filters applied.
      #
      # @return [Stream]
      def filtered_stream
        if @stream
          if @filtered_stream.nil?
            @filtered_stream = @stream.dup

            @filters.each do |(filter_name, params)|
              filter = PDF::Core::Filters.const_get(filter_name)
              if filter
                @filtered_stream = filter.encode(@filtered_stream, params)
              end
            end
          end

          @filtered_stream
        end
      end

      # Size of data in the stream
      #
      # @return [Integer]
      def length
        @stream.length
      end

      # Serialized stream data
      #
      # @return [String]
      def object
        if filtered_stream
          "stream\n#{filtered_stream}\nendstream\n"
        else
          ''
        end
      end

      # Stream dictionary
      #
      # @return [Hash]
      def data
        if @stream
          filter_names = @filters.names
          filter_params = @filters.decode_params

          d = {
            Length: filtered_stream.length,
          }
          if filter_names.any?
            d[:Filter] = filter_names
          end
          if filter_params.any? { |f| !f.nil? }
            d[:DecodeParms] = filter_params
          end

          d
        else
          {}
        end
      end

      # String representation of the stream for debugging purposes.
      #
      # @return [String]
      def inspect
        format(
          '#<%<class>s:0x%<object_id>014x @stream=%<stream>s, @filters=%<filters>s>',
          class: self.class.name,
          object_id: object_id,
          stream: @stream.inspect,
          filters: @filters.inspect,
        )
      end
    end
  end
end