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:

: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:

: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:

: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:

: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