filename,'r'); fseek($fh,$offset); } $result = collect(); while ($rp < $size) { $read = $atom ? substr($atom,$rp,8) : fread($fh,8); $rp += strlen($read); $header = unpack('Nsize/a4atom',$read); // For mdat atoms, if size = 1, the true size is in the 64 bit extended header if (($header['atom'] === 'mdat') && ($header['size'] === 1)) throw new \Exception(sprintf('%s:! We havent handed large QT files yet.',self::LOGKEY)); // Load our class for this supplier $class = $class_prefix.$header['atom']; $data = $atom ? substr($atom,$rp,$header['size']-8) : ($header['size']-8 && ($header['size']-8 <= static::record_size) ? fread($fh,$header['size']-8) : NULL); if ($header['size'] >= 8) { $o = class_exists($class) ? new $class($offset+$rp,$header['size']-8,$this->filename,$data,$passthru) : new $unknown($offset+$rp,$header['size']-8,$this->filename,$header['atom'],$data); $result->push($o); $rp += $header['size']-8; // Only need to seek if we didnt read all the data if ((! $atom) && ($header['size']-8 > static::record_size)) fseek($fh,$offset+$rp); } else { dd([get_class($this) => $data]); } // Work out if data from the last atom next to be passed onto the next one if ($callback) $passthru = $callback($o); } if (! $atom) { fclose($fh); unset($fh); } return $result; } /** * Recursively look through our object hierarchy of atoms for a specific atom class * * @param string $subatom * @param int|NULL $expect * @param int $depth * @return Collection|Atom|NULL * @throws \Exception */ public function find_atoms(string $subatom,?int $expect=NULL,int $depth=100): Collection|Atom|NULL { if (! isset($this->atoms) || ($depth < 0)) return NULL; $subatomo = $this->atoms->filter(fn($item)=>get_class($item)===$subatom); $subatomo = $subatomo ->merge($this->atoms->map(fn($item)=>$item->find_atoms($subatom,NULL,$depth-1)) ->filter(fn($item)=>$item ? $item->count() : NULL) ->flatten()); if (! $subatomo->count()) return $subatomo; if ($expect && ($subatomo->count() !== $expect)) throw new \Exception(sprintf('! Expected %d subatoms of %s, but have %d',$expect,$subatom,$subatomo->count())); return ($expect === 1) ? $subatomo->pop() : $subatomo; } }