Class: Origami::Array
- Inherits:
-
Array
- Object
- Array
- Origami::Array
- Includes:
- Object
- Defined in:
- lib/origami/array.rb,
lib/origami/obfuscation.rb
Overview
Class representing an Array Object. Arrays contain a set of Object.
Direct Known Subclasses
Constant Summary collapse
- TOKENS =
:nodoc:
%w{ [ ] }
- @@regexp_open =
Regexp.new(WHITESPACES + Regexp.escape(TOKENS.first) + WHITESPACES)
- @@regexp_close =
Regexp.new(WHITESPACES + Regexp.escape(TOKENS.last) + WHITESPACES)
Instance Attribute Summary collapse
-
#names_cache ⇒ Object
readonly
Returns the value of attribute names_cache.
-
#strings_cache ⇒ Object
readonly
Returns the value of attribute strings_cache.
-
#xref_cache ⇒ Object
readonly
Returns the value of attribute xref_cache.
Attributes included from Object
#file_offset, #generation, #no, #objstm_offset, #parent
Class Method Summary collapse
-
.of(klass, *klasses, length: nil) ⇒ Object
Parameterized Array class with additional typing information.
-
.parse(stream, parser = nil, hint_type: nil) ⇒ Object
:nodoc:.
Instance Method Summary collapse
- #+(other) ⇒ Object
- #<<(item) ⇒ Object (also: #push)
- #[]=(key, val) ⇒ Object
- #cast_to(type, parser = nil) ⇒ Object
- #concat(*arys) ⇒ Object
- #copy ⇒ Object
-
#initialize(data = [], parser = nil, hint_type: nil) ⇒ Array
constructor
Creates a new PDF Array Object.
- #pre_build ⇒ Object
-
#to_a ⇒ Object
(also: #value)
Converts self into a Ruby array.
- #to_obfuscated_str ⇒ Object
-
#to_s ⇒ Object
:nodoc:.
Methods included from Object
#<=>, #document, #export, included, #indirect?, #indirect_parent, #logicalize, #logicalize!, #native_type, #post_build, #reference, #set_document, #set_indirect, skip_until_next_obj, #solve, #to_o, #type, typeof, #version_required, #xrefs
Constructor Details
#initialize(data = [], parser = nil, hint_type: nil) ⇒ Array
Creates a new PDF Array Object.
- data
-
An array of objects.
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 |
# File 'lib/origami/array.rb', line 45 def initialize(data = [], parser = nil, hint_type: nil) raise TypeError, "Expected type Array, received #{data.class}." unless data.is_a?(::Array) super() @strings_cache = [] @names_cache = [] @xref_cache = {} data.each_with_index do |value, index| value = value.to_o if Origami::OPTIONS[:enable_type_guessing] index_type = hint_type.is_a?(::Array) ? hint_type[index % hint_type.size] : hint_type if index_type.is_a?(::Array) and not value.is_a?(Reference) index_type = index_type.find {|type| type < value.class } end if index_type.is_a?(Class) and index_type < value.class value = value.cast_to(index_type, parser) end if index_type and parser and Origami::OPTIONS[:enable_type_propagation] if value.is_a?(Reference) parser.defer_type_cast(value, index_type) end end end # Cache object value for fast search. cache_value(value) self.push(value) end end |
Instance Attribute Details
#names_cache ⇒ Object (readonly)
Returns the value of attribute names_cache.
39 40 41 |
# File 'lib/origami/array.rb', line 39 def names_cache @names_cache end |
#strings_cache ⇒ Object (readonly)
Returns the value of attribute strings_cache.
39 40 41 |
# File 'lib/origami/array.rb', line 39 def strings_cache @strings_cache end |
#xref_cache ⇒ Object (readonly)
Returns the value of attribute xref_cache.
39 40 41 |
# File 'lib/origami/array.rb', line 39 def xref_cache @xref_cache end |
Class Method Details
.of(klass, *klasses, length: nil) ⇒ Object
Parameterized Array class with additional typing information. Example: Array.of(Integer)
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/origami/array.rb', line 198 def self.of(klass, *klasses, length: nil) Class.new(self) do const_set('ARRAY_TYPE', (klasses.empty? and not klass.is_a?(::Array)) ? klass : [ klass ].concat(klasses)) const_set('STATIC_LENGTH', length) def initialize(data = [], parser = nil) super(data, parser, hint_type: self.class.const_get('ARRAY_TYPE')) end def pre_build #:nodoc: do_type_check if Origami::OPTIONS[:enable_type_checking] super end def self.parse(stream, parser = nil) super(stream, parser, hint_type: const_get('ARRAY_TYPE')) end def do_type_check #:nodoc: static_length = self.class.const_get('STATIC_LENGTH') array_type = self.class.const_get('ARRAY_TYPE') if static_length and self.length != static_length STDERR.puts "Warning: object #{self.class.name} has unexpected length #{self.length} (should be #{static_length})" end self.each_with_index do |object, index| index_type = array_type.is_a?(::Array) ? array_type[index % array_type.size] : array_type begin object_value = object.solve rescue InvalidReferenceError STDERR.puts "Warning: in object #{self.class}, invalid reference at index #{index}" next end unless object_value.is_a?(index_type) STDERR.puts "Warning: object #{self.class.name || 'Array'} should be composed of #{index_type.name} at index #{index} (got #{object_value.type} instead)" end end end end end |
.parse(stream, parser = nil, hint_type: nil) ⇒ Object
:nodoc:
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/origami/array.rb', line 86 def self.parse(stream, parser = nil, hint_type: nil) #:nodoc: data = [] offset = stream.pos if not stream.skip(@@regexp_open) raise InvalidArrayObjectError, "No token '#{TOKENS.first}' found" end while stream.skip(@@regexp_close).nil? do type = Object.typeof(stream) raise InvalidArrayObjectError, "Bad embedded object format" if type.nil? value = type.parse(stream, parser) data << value end array = Array.new(data, parser, hint_type: hint_type) array.file_offset = offset array end |
Instance Method Details
#+(other) ⇒ Object
133 134 135 136 137 138 |
# File 'lib/origami/array.rb', line 133 def +(other) a = Origami::Array.new(self.to_a + other.to_a) a.no, a.generation = @no, @generation a end |
#<<(item) ⇒ Object Also known as: push
140 141 142 143 144 145 |
# File 'lib/origami/array.rb', line 140 def <<(item) obj = item.to_o obj.parent = self unless obj.indirect? super(obj) end |
#[]=(key, val) ⇒ Object
148 149 150 151 152 153 |
# File 'lib/origami/array.rb', line 148 def []=(key, val) key, val = key.to_o, val.to_o super(key.to_o, val.to_o) val.parent = self unless val.indirect? end |
#cast_to(type, parser = nil) ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/origami/array.rb', line 179 def cast_to(type, parser = nil) super(type) cast = type.new(self.copy, parser) cast.parent = self.parent cast.no, cast.generation = self.no, self.generation if self.indirect? cast.set_indirect(true) cast.set_document(self.document) cast.file_offset = self.file_offset # cast can replace self end cast end |
#concat(*arys) ⇒ Object
155 156 157 158 159 160 161 162 163 164 |
# File 'lib/origami/array.rb', line 155 def concat(*arys) arys.each do |ary| ary.each do |e| val = e.to_o val.parent = self unless val.indirect? self.push(val) end end end |
#copy ⇒ Object
166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/origami/array.rb', line 166 def copy copy = self.class.new self.each do |obj| copy << obj.copy end copy.parent = @parent copy.no, copy.generation = @no, @generation copy.set_indirect(true) if self.indirect? copy.set_document(@document) if self.indirect? copy end |
#pre_build ⇒ Object
80 81 82 83 84 |
# File 'lib/origami/array.rb', line 80 def pre_build self.map!{|obj| obj.to_o} super end |
#to_a ⇒ Object Also known as: value
Converts self into a Ruby array.
111 112 113 |
# File 'lib/origami/array.rb', line 111 def to_a super.map(&:value) end |
#to_obfuscated_str ⇒ Object
154 155 156 157 158 159 160 161 162 163 |
# File 'lib/origami/obfuscation.rb', line 154 def content = TOKENS.first + Obfuscator.junk_spaces self.each do |entry| content << entry.to_o. + Obfuscator.junk_spaces end content << TOKENS.last super(content) end |
#to_s ⇒ Object
:nodoc:
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/origami/array.rb', line 116 def to_s #:nodoc: content = "#{TOKENS.first} " self.each do |entry| entry = entry.to_o case entry when Dictionary # Do not indent dictionaries inside of arrays. content << entry.to_s(indent: 0) << ' ' else content << entry.to_s << ' ' end end content << TOKENS.last super(content) end |