diff --git a/src/Magic.php b/src/Magic.php deleted file mode 100644 index 21a3c27..0000000 --- a/src/Magic.php +++ /dev/null @@ -1,177 +0,0 @@ -1 -- byte number to begin checking from. ">" indicates a dependency - * upon the previous non-">" line - * o 2 -- type of data to match. Can be one of following - * - byte (single character) - * - short (machine-order 16-bit integer) - * - long (machine-order 32-bit integer) - * - string (arbitrary-length string) - * - date (long integer date (seconds since Unix epoch/1970)) - * - beshort (big-endian 16-bit integer) - * - belong (big-endian 32-bit integer) - * - bedate (big-endian 32-bit integer date) - * - leshort (little-endian 16-bit integer) - * - lelong (little-endian 32-bit integer) - * - ledate (little-endian 32-bit integer date) - * o 3 -- contents of data to match - * o 4 -- file description/MIME type if matched - * o 5 -- optional MIME encoding if matched and if above was a MIME type - * - * @package php-reader - * @author Sven Vollbehr - * @copyright Copyright (c) 2006-2008 PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class Magic -{ - /** @var string */ - private $_magic; - - /** - * Reads the magic information from given magic file. - * - * @param string $filename The path to the magic file. - */ - public function __construct($filename) - { - $reader = new Reader($filename); - $this->_magic = $reader->read($reader->getSize()); - } - - /** - * 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 - * false. - * - * @param string $filename The file path whose type to determine. - * @param string $default The default value. - * @return string|false - */ - public function getType($filename, $default = false) - { - $reader = new Reader($filename); - - $parentOffset = 0; - foreach (preg_split("/^/m", $this->_magic) as $line) { - $chunks = array(); - if (!preg_match("/^(?P>?)(?P\d+)\s+(?P\S+)" . - "\s+(?P\S+)(?:\s+(?P[a-z]+\/[a-z-" . - "0-9]+)?(?:\s+(?P.+))?)?$/", $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/1970) - $data = $reader->readInt64BE(); - break; - case "beshort": // big-endian 16-bit integer - $data = $reader->readUInt16BE(); - break; - case "belong": // big-endian 32-bit integer - 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 - 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 $chunks["Description"]; - } - } - return $default; - } -} diff --git a/src/Reader.php b/src/Reader.php deleted file mode 100644 index d6c185b..0000000 --- a/src/Reader.php +++ /dev/null @@ -1,234 +0,0 @@ - - * @author Ryan Butterfield - * @copyright Copyright (c) 2006-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -class Reader -{ - /** @var resource */ - private $_fd; - - /** @var integer */ - private $_size; - - /** - * Constructs the Reader class with given file. - * - * @param string $filename The path to the file. - * @param string $mode The type of access. - * @throws Reader_Exception if the file cannot be read. - */ - public function __construct($filename, $mode = "rb") - { - if (is_resource($filename) && - in_array(get_resource_type($filename), array("file", "stream"))) - $this->_fd = $filename; - else if (($this->_fd = fopen($filename, $mode)) === false) - throw new Reader_Exception("Unable to open file:" . $filename); - - fseek($this->_fd, 0, SEEK_END); - $this->_size = ftell($this->_fd); - fseek($this->_fd, 0); - } - - /** - * Closes the file. - */ - public function __destruct() - { - @fclose($this->_fd); - } - - /** - * Checks whether there is more to be read in the file. Returns - * true if the end of the file has not yet been reached; - * false otherwise. - * - * @return boolean - */ - public function available() - { - return $this->getOffset() < $this->_size; - } - - /** - * Jumps size amount of bytes in the file stream. - * - * @param integer $size The amount of bytes. - * @return void - * @throws Reader_Exception if size attribute is negative. - */ - public function skip($size) - { - if ($size < 0) - throw new Reader_Exception("Invalid argument"); - if ($size == 0) - return; - fseek($this->_fd, $size, SEEK_CUR); - } - - /** - * Reads length amount of bytes from the file stream. - * - * @param integer $length The amount of bytes. - * @return string - * @throws Reader_Exception if length attribute is negative. - */ - public function read($length) - { - if ($length < 0) - throw new Reader_Exception("Invalid argument"); - if ($length == 0) - return ""; - return fread($this->_fd, $length); - } - - /** - * Returns the current point of operation. - * - * @return integer - */ - public function getOffset() - { - return ftell($this->_fd); - } - - /** - * Sets the point of operation, ie the cursor offset value. The offset can - * also be set to a negative value when it is interpreted as an offset from - * the end of the file instead of the beginning. - * - * @param integer $offset The new point of operation. - * @return void - */ - public function setOffset($offset) - { - fseek($this->_fd, $offset < 0 ? $this->_size + $offset : $offset); - } - - /** - * Returns the file size in bytes. - * - * @return integer - */ - public function getSize() { return $this->_size; } - - /** - * Magic function so that $obj->value will work. - * - * @param string $name The field name. - * @return mixed - */ - public function __get($name) - { - if (method_exists($this, "get" . ucfirst(strtolower($name)))) - return call_user_func(array($this, "get" . ucfirst(strtolower($name)))); - else throw new Reader_Exception("Unknown field: " . $name); - } - - /** - * Magic function so that assignments with $obj->value will work. - * - * @param string $name The field name. - * @param string $value The field value. - * @return mixed - */ - public function __set($name, $value) - { - if (method_exists($this, "set" . ucfirst(strtolower($name)))) - call_user_func - (array($this, "set" . ucfirst(strtolower($name))), $value); - else throw new Reader_Exception("Unknown field: " . $name); - } - - /** - * Magic function to delegate the call to helper methods of - * Transform class to transform read data in another format. - * - * The read data length is determined from the helper method name. For methods - * where arbitrary data lengths are accepted a parameter can be used to - * specify the length. - * - * @param string $method The method to be called. - * @param string $params The parameters should the function accept them. - * @return mixed - * @throws Reader_Exception if no such transformer is implemented - */ - public function __call($method, $params) - { - $chunks = array(); - - // To keep compatibility with PHP 5.0.0 we use a static array instead of - // method_exists to check if a method of the Transform class can be called. - static $methods = array( - "isLittleEndian", "isBigEndian", "toInt64LE", "fromInt64LE", "toInt64BE", - "fromInt64BE", "toInt32", "fromInt32", "toInt32LE", "fromInt32LE", - "toInt32BE", "fromInt32BE", "toUInt32LE", "fromUInt32LE", "toUInt32BE", - "fromUInt32BE", "toInt16", "fromInt16", "toInt16LE", "fromInt16LE", - "toInt16BE", "fromInt16BE", "toUInt16LE", "fromUInt16LE", "toUInt16BE", - "fromUInt16BE", "toInt8", "fromInt8", "toUInt8", "fromUInt8", "toFloat", - "fromFloat", "toFloatLE", "fromFloatLE", "toFloatBE", "fromFloatBE", - "toString8", "fromString8", "toString16", "fromString16", "toString16LE", - "fromString16LE", "toString16BE", "fromString16BE", "toHHex", "fromHHex", - "toLHex", "fromLHex", "toGUID", "fromGUID" - ); - if (preg_match - ("/read([a-z]{3,6})?(\d{1,2})?(?:LE|BE)?/i", $method, $chunks) && - in_array(preg_replace("/^read/", "from", $method), $methods)) - return call_user_func - (array("Transform", preg_replace("/^read/", "from", $method)), - $this->read(preg_match("/String|(?:H|L)Hex/", $chunks[1]) ? - (isset($params[0]) ? $params[0] : 1) : - ($chunks[1] == "GUID" ? 16 : $chunks[2] / 8))); - else throw new Reader_Exception("Unknown method: " . $method); - } -} diff --git a/src/Zend/Mime/Magic.php b/src/Zend/Mime/Magic.php new file mode 100644 index 0000000..82fb2e8 --- /dev/null +++ b/src/Zend/Mime/Magic.php @@ -0,0 +1,170 @@ +1 -- byte number to begin checking from. '>' indicates a dependency + * upon the previous non-'>' line + * o 2 -- type of data to match. Can be one of following + * - byte (single character) + * - short (machine-order 16-bit integer) + * - long (machine-order 32-bit integer) + * - string (arbitrary-length string) + * - date (long integer date (seconds since Unix epoch/1970)) + * - beshort (big-endian 16-bit integer) + * - belong (big-endian 32-bit integer) + * - bedate (big-endian 32-bit integer date) + * - leshort (little-endian 16-bit integer) + * - lelong (little-endian 32-bit integer) + * - ledate (little-endian 32-bit integer date) + * o 3 -- contents of data to match + * o 4 -- file description/MIME type if matched + * o 5 -- optional MIME encoding if matched and if above was a MIME type + * + * @category Zend + * @package Zend_Mime + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Mime_Magic +{ + /** @var string */ + private $_magic; + + /** + * Reads the magic information from given magic file. + * + * @param string $filename The path to the magic file. + */ + public function __construct($filename) + { + $reader = new Zend_Io_FileReader($filename); + $this->_magic = $reader->read($reader->getSize()); + } + + /** + * 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 null. + * + * @param string $filename The file path whose type to determine. + * @param string $default The default value. + * @return string|false + */ + public function getType($filename, $default = null) + { + $reader = new Zend_Io_FileReader($filename); + + $parentOffset = 0; + foreach (preg_split('/^/m', $this->_magic) as $line) { + $chunks = array(); + if (!preg_match("/^(?P>?)(?P\d+)\s+(?P\S+)\s+(?P\S+)(?:\s+(?P[a-" . + "z]+\/[a-z-0-9]+)?(?:\s+(?P.+))?)?$/", + $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 + 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 + 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 $chunks['Description']; + } + } + } + return $default; + } +}