Пример #1
0
 /**
  * Returns the recognized MIME type/description of the given file. The type
  * is determined by the content using magic bytes characteristic for the
  * particular file type.
  *
  * If the type could not be found, the function returns the default value,
  * or <var>null</var>.
  *
  * @param string $filename The file path whose type to determine.
  * @param string $default  The default value.
  * @return string|false
  */
 public function getMimeType($filename, $default = null)
 {
     $reader = new HausDesign_Io_FileReader($filename);
     $parentOffset = 0;
     foreach (preg_split('/^/m', $this->_magic) as $line) {
         $chunks = array();
         if (!preg_match("/^(?P<Dependant>>?)(?P<Byte>\\d+)\\s+(?P<MatchType" . ">\\S+)\\s+(?P<MatchData>\\S+)(?:\\s+(?P<MIMEType>[a-" . "z]+\\/[a-z-0-9]+)?(?:\\s+(?P<Description>.?+))?)?\$/", $line, $chunks)) {
             continue;
         }
         if ($chunks['Dependant']) {
             $reader->setOffset($parentOffset);
             $reader->skip($chunks['Byte']);
         } else {
             $reader->setOffset($parentOffset = $chunks['Byte']);
         }
         $matchType = strtolower($chunks['MatchType']);
         $matchData = preg_replace(array("/\\\\ /", "/\\\\\\\\/", "/\\\\([0-7]{1,3})/e", "/\\\\x([0-9A-Fa-f]{1,2})/e", "/0x([0-9A-Fa-f]+)/e"), array(" ", "\\\\", "pack(\"H*\", base_convert(\"\$1\", 8, 16));", "pack(\"H*\", \"\$1\");", "hexdec(\"\$1\");"), $chunks["MatchData"]);
         switch ($matchType) {
             case 'byte':
                 // single character
                 $data = $reader->readInt8();
                 break;
             case 'short':
                 // machine-order 16-bit integer
                 $data = $reader->readInt16();
                 break;
             case 'long':
                 // machine-order 32-bit integer
                 $data = $reader->readInt32();
                 break;
             case 'string':
                 // arbitrary-length string
                 $data = $reader->readString8(strlen($matchData));
                 break;
             case 'date':
                 // long integer date (seconds since Unix epoch)
                 $data = $reader->readInt64BE();
                 break;
             case 'beshort':
                 // big-endian 16-bit integer
                 $data = $reader->readUInt16BE();
                 break;
             case 'belong':
                 // big-endian 32-bit integer
                 // break intentionally omitted
             // big-endian 32-bit integer
             // break intentionally omitted
             case 'bedate':
                 // big-endian 32-bit integer date
                 $data = $reader->readUInt32BE();
                 break;
             case 'leshort':
                 // little-endian 16-bit integer
                 $data = $reader->readUInt16LE();
                 break;
             case 'lelong':
                 // little-endian 32-bit integer
                 // break intentionally omitted
             // little-endian 32-bit integer
             // break intentionally omitted
             case 'ledate':
                 // little-endian 32-bit integer date
                 $data = $reader->readUInt32LE();
                 break;
             default:
                 $data = null;
                 break;
         }
         if (strcmp($data, $matchData) == 0) {
             if (!empty($chunks['MIMEType'])) {
                 return $chunks['MIMEType'];
             }
             if (!empty($chunks['Description'])) {
                 return rtrim($chunks['Description'], "\n");
             }
         }
     }
     return $default;
 }