/** * Recupera o Mime-type de um arquivo * @param File $file * @return string */ public function getMimeType( File $file ) { $ret = false; $iterator = $this->getIterator(); $parser = new MagicParser( $file , $this ); if ( !$file->isOpened() ) $file->open( 'r' ); for ( $iterator->rewind() ; $iterator->valid() ; $iterator->next() ) { if ( ( $ret = $parser->parse( $iterator ) ) !== false ) { break; } } return $ret; }
/** * Interpreta a linha do arquivo magic e compara com o arquivo passado para descobrir * o Content-Type do arquivo * @param Iterator $iterator */ public function parse( Iterator $iterator ) { $ret = false; $match = array(); $line = preg_replace( array( "/\r\n|\r|\n/" , '/\s{2,}/' ) , array( null , "\t" ) , $iterator->current() ); if ( preg_match( "/^(?<d>\\>)?(?<b>\\d+)\\s*(?<t>(byte|string|(be|le)?(short|long|date)))\\s+(?<c>[^\t]+)(\\s*(?<mt>[^\t]+)(\\s*(?<me>[^\t]+))?)?$/s" , $line , $match ) ) { $byteNumber = (int) $match[ 'b' ]; switch ( $match[ 't' ] ) { case 'string' : $match[ 'c' ] = stripcslashes( $match[ 'c' ] ); case 'byte' : $dataContents = $match[ 'c' ]; break; case 'short' : $dataContents = pack( 'S' , $this->numberConvert( $match[ 'c' ] ) ); break; case 'beshort' : $dataContents = pack( 'n' , $this->numberConvert( $match[ 'c' ] ) ); break; case 'leshort' : $dataContents = pack( 'v' , $this->numberConvert( $match[ 'c' ] ) ); break; case 'long' : $dataContents = pack( 'L' , $this->numberConvert( $match[ 'c' ] ) ); break; case 'belong' : $dataContents = pack( 'N' , $this->numberConvert( $match[ 'c' ] ) ); break; case 'lelong' : $dataContents = pack( 'V' , $this->numberConvert( $match[ 'c' ] ) ); break; // TODO: implementar os tipos date, ledate e bedate case 'date' : case 'ledate' : case 'bedate' : default : return false; } if ( $this->compare( $byteNumber , $dataContents ) ) { $ret = $match[ 'mt' ]; if ( !empty( $match[ 'me' ] ) ) { $ret = sprintf( '%s; charset=%s' , $ret , $match[ 'me' ] ); } if ( empty( $match[ 'd' ] ) ) { $offset = $this->magic->tell(); $magic = new MagicParser( $this->file , $this->magic ); do { $iterator->next(); $current = $iterator->current(); if ( substr( $current , 1 , 1 ) != '>' ) { $this->magic->seek( $offset ); break; } else { $offset = $this->magic->tell(); if ( ( $newRet = $magic->parse( $iterator ) ) !== false ) { $ret = & $newRet; for (; $iterator->valid() ; $iterator->next() ) { if ( substr( $iterator->current() , 1 , 1 ) == '>' ) { $this->magic->seek( $offset ); break 2; } else { $offset = $this->magic->tell(); } } } } } while ( $iterator->valid() && ( substr( $current , 1 , 1 ) == '>' ) ); } } } return $ret; }