class Origami::Array
Arrays contain a set of Object.
Class representing an Array Object.
def self.of(klass, *klasses, length: nil)
Example: Array.of(Integer)
Parameterized Array class with additional typing information.
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 valid_type = case index_type when Class object_value.is_a?(index_type) when Array index_type.any? { |type| object_value.is_a?(type) } else true end unless valid_type allowed = Array(index_type).map(&:name).join('|') STDERR.puts "Warning: object #{self.class.name} should be one of [#{allowed}] at index #{index} (got #{object_value.type} instead)" end end end end end
def self.parse(stream, parser = nil, hint_type: nil) #:nodoc:
def self.parse(stream, parser = nil, hint_type: nil) #:nodoc: scanner = Parser.init_scanner(stream) offset = scanner.pos data = [] if not scanner.skip(@@regexp_open) raise InvalidArrayObjectError, "No token '#{TOKENS.first}' found" end while scanner.skip(@@regexp_close).nil? do type = Object.typeof(scanner) raise InvalidArrayObjectError, "Bad embedded object format" if type.nil? value = type.parse(scanner, parser) data << value end array = Array.new(data, parser, hint_type: hint_type) array.file_offset = offset array end
def self.parse(stream, parser = nil)
def self.parse(stream, parser = nil) super(stream, parser, hint_type: const_get('ARRAY_TYPE')) end
def +(other)
def +(other) a = Origami::Array.new(self.to_a + other.to_a) a.no, a.generation = @no, @generation a end
def <<(item)
def <<(item) super link_object(item) end
def []=(index, item)
def []=(index, item) super(index, link_object(item)) end
def concat(*arys)
def concat(*arys) self.push(*arys.flatten) end
def do_type_check #:nodoc:
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 valid_type = case index_type when Class object_value.is_a?(index_type) when Array index_type.any? { |type| object_value.is_a?(type) } else true end unless valid_type allowed = Array(index_type).map(&:name).join('|') STDERR.puts "Warning: object #{self.class.name} should be one of [#{allowed}] at index #{index} (got #{object_value.type} instead)" end end end
def initialize(data = [], parser = nil, hint_type: nil)
_data_:: An array of objects.
Creates a new PDF Array Object.
def initialize(data = [], parser = nil, hint_type: nil) raise TypeError, "Expected type Array, received #{data.class}." unless data.is_a?(::Array) super() 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 self.push(value) end end
def initialize(data = [], parser = nil)
def initialize(data = [], parser = nil) super(data, parser, hint_type: self.class.const_get('ARRAY_TYPE')) end
def insert(index, *items)
def insert(index, *items) items.reverse_each do |item| super(index, link_object(item)) end self end
def pre_build
def pre_build self.map!(&:to_o) super end
def pre_build #:nodoc:
def pre_build #:nodoc: do_type_check if Origami::OPTIONS[:enable_type_checking] super end
def push(*items)
def push(*items) items.each {|item| self << item } end
def to_a
Converts self into a Ruby array.
def to_a super.map(&:value) end
def to_obfuscated_str
def to_obfuscated_str content = TOKENS.first + Obfuscator.junk_spaces self.each do |entry| content << entry.to_o.to_obfuscated_str + Obfuscator.junk_spaces end content << TOKENS.last super(content) end
def to_s(eol: $/) #:nodoc:
def to_s(eol: $/) #:nodoc: content = TOKENS.first.dup content << self.map {|entry| entry = entry.to_o case entry when Dictionary # Do not indent dictionaries inside of arrays. entry.to_s(indent: 0, eol: eol) else entry.to_s(eol: eol) end }.join(' ') content << TOKENS.last super(content, eol: eol) end