lib/parsers/moov_parser/decoder.rb
# Recursive descent parser - will drill down to atoms which
# we know are permitted to have leaf/branch atoms within itself,
# and will attempt to recover the data fields for leaf atoms
Recursive descent parser - will drill down to atoms which
we know are permitted to have leaf/branch atoms within itself,
and will attempt to recover the data fields for leaf atoms
Recursive descent parser - will drill down to atoms which we know are permitted to have leaf / branch atoms within itself and will attempt to recover the data fields for leaf atoms
def extract_atom_stream(io, max_read, current_branch = [])
    initial_pos = io.pos
    atoms = []
    MAX_ATOMS_AT_LEVEL.times do
      atom_pos = io.pos
      break if atom_pos - initial_pos >= max_read
      size_and_type = io.read(4 + 4)
      break if size_and_type.to_s.bytesize < 8
      atom_size, atom_type = size_and_type.unpack('Na4')
      atom_size = read_64bit_uint(io) if atom_size == 1
      size_of_atom_type_and_size = io.pos - atom_pos
      atom_size_sans_header = atom_size - size_of_atom_type_and_size
      children, fields = if KNOWN_BRANCH_AND_LEAF_ATOM_TYPES.include?(atom_type)
        parse_atom_children_and_data_fields(io, atom_size_sans_header, atom_type, current_branch)
      elsif KNOWN_BRANCH_ATOM_TYPES.include?(atom_type)
        [extract_atom_stream(io, atom_size_sans_header, current_branch + [atom_type]), nil]
      else 
        [nil, parse_atom_fields_per_type(io, atom_size_sans_header, atom_type)]
      end
      atoms << Atom.new(atom_pos, atom_size, atom_type, current_branch + [atom_type], children, fields)
      io.seek(atom_pos + atom_size)
    end
    atoms
  end
def extract_atom_stream ( io , max_read , current_branch = [ ] ) initial_pos = io . pos atoms = [ ] MAX_ATOMS_AT_LEVEL . times do atom_pos = io . pos break if atom_pos - initial_pos >= max_read size_and_type = io . read ( 4 + 4 ) break if size_and_type . to_s . bytesize < 8 atom_size , atom_type = size_and_type . unpack ( 'Na4' ) atom_size = read_64bit_uint ( io ) if atom_size == 1 size_of_atom_type_and_size = io . pos - atom_pos atom_size_sans_header = atom_size - size_of_atom_type_and_size children , fields = if KNOWN_BRANCH_AND_LEAF_ATOM_TYPES . include? ( atom_type ) parse_atom_children_and_data_fields ( io , atom_size_sans_header , atom_type , current_branch ) elsif KNOWN_BRANCH_ATOM_TYPES . include? ( atom_type ) [ extract_atom_stream ( io , atom_size_sans_header , current_branch + [ atom_type ] ) , nil ] else [ nil , parse_atom_fields_per_type ( io , atom_size_sans_header , atom_type ) ] end atoms << Atom . new ( atom_pos , atom_size , atom_type , current_branch + [ atom_type ] , children , fields ) io . seek ( atom_pos + atom_size ) end atoms end
Recursive descent parser - will drill down to atoms which
we know are permitted to have leaf/branch atoms within itself,
and will attempt to recover the data fields for leaf atoms
Recursive descent parser - will drill down to atoms which we know are permitted to have leaf / branch atoms within itself and will attempt to recover the data fields for leaf atoms
# If atom_size is specified to be 1, it is larger than what fits into the # 4 bytes and we need to read it right after the atom type # We are allowed to read what comes after # the atom size and atom type, but not any more than that # Assume leaf atom
io
max_read
current_branch