diff cake/libs/magic_db.php @ 0:261e66bd5a0c

hg init
author Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp>
date Sun, 24 Jul 2011 21:08:31 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cake/libs/magic_db.php	Sun Jul 24 21:08:31 2011 +0900
@@ -0,0 +1,302 @@
+<?php
+/**
+ * MagicDb parser and file analyzer
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @package       cake
+ * @subpackage    cake.cake.libs
+ * @since         CakePHP(tm) v 1.2.0
+ * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+if (!class_exists('Object')) {
+	require LIBS . 'object.php';
+}
+if (!class_exists('File')) {
+	require LIBS . 'file.php';
+}
+
+/**
+ * A class to parse and use the MagicDb for file type analysis
+ *
+ * @package       cake.tests
+ * @subpackage    cake.tests.cases.libs
+ */
+class MagicDb extends Object {
+
+/**
+ * Holds the parsed MagicDb for this class instance
+ *
+ * @var array
+ */
+	var $db = array();
+
+/**
+ * Reads a MagicDb from various formats
+ *
+ * @var $magicDb mixed Can be an array containing the db, a magic db as a string, or a filename pointing to a magic db in .db or magic.db.php format
+ * @return boolean Returns false if reading / validation failed or true on success.
+ * @author        Felix
+ */
+	function read($magicDb = null) {
+		if (!is_string($magicDb) && !is_array($magicDb)) {
+			return false;
+		}
+		if (is_array($magicDb) || strpos($magicDb, '# FILE_ID DB') === 0) {
+			$data = $magicDb;
+		} else {
+			$File =& new File($magicDb);
+			if (!$File->exists()) {
+				return false;
+			}
+			if ($File->ext() == 'php') {
+				include($File->pwd());
+				$data = $magicDb;
+			} else {
+				// @TODO: Needs test coverage
+				$data = $File->read();
+			}
+		}
+
+		$magicDb = $this->toArray($data);
+		if (!$this->validates($magicDb)) {
+			return false;
+		}
+		return !!($this->db = $magicDb);
+	}
+
+/**
+ * Parses a MagicDb $data string into an array or returns the current MagicDb instance as an array
+ *
+ * @param string $data A MagicDb string to turn into an array
+ * @return array A parsed MagicDb array or an empty array if the $data param was invalid. Returns the db property if $data is not set.
+ * @access public
+ */
+	function toArray($data = null) {
+		if (is_array($data)) {
+			return $data;
+		}
+		if ($data === null) {
+			return $this->db;
+		}
+
+		if (strpos($data, '# FILE_ID DB') !== 0) {
+			return array();
+		}
+
+		$lines = explode("\r\n", $data);
+		$db = array();
+
+		$validHeader = count($lines) > 3
+					&& preg_match('/^# Date:([0-9]{4}-[0-9]{2}-[0-9]{2})$/', $lines[1], $date)
+					&& preg_match('/^# Source:(.+)$/', $lines[2], $source)
+					&& strlen($lines[3]) == 0;
+		if (!$validHeader) {
+			return $db;
+		}
+
+		$db = array('header' => array('Date' => $date[1], 'Source' => $source[1]), 'database' => array());
+		$lines = array_splice($lines, 3);
+
+		$format = array();
+		while (!empty($lines)) {
+			$line = array_shift($lines);
+			if (isset($line[0]) && $line[0] == '#' || empty($line)) {
+				continue;
+			}
+
+			$columns = explode("\t", $line);
+			if (in_array($columns[0]{0}, array('>', '&'))) {
+				$format[] = $columns;
+			} elseif (!empty($format)) {
+				$db['database'][] = $format;
+				$format = array($columns);
+			} else {
+				$format = array($columns);
+			}
+		}
+
+		return $db;
+	}
+
+/**
+ * Returns true if the MagicDb instance or the passed $magicDb is valid
+ *
+ * @param mixed $magicDb A $magicDb string / array to validate (optional)
+ * @return boolean True if the $magicDb / instance db validates, false if not
+ * @access public
+ */
+	function validates($magicDb = null) {
+		if (is_null($magicDb)) {
+			$magicDb = $this->db;
+		} elseif (!is_array($magicDb)) {
+			$magicDb = $this->toArray($magicDb);
+		}
+
+		return isset($magicDb['header'], $magicDb['database']) && is_array($magicDb['header']) && is_array($magicDb['database']);
+	}
+
+/**
+ * Analyzes a given $file using the currently loaded MagicDb information based on the desired $options
+ *
+ * @param string $file Absolute path to the file to analyze
+ * @param array $options TBT
+ * @return mixed
+ * @access public
+ */
+	function analyze($file, $options = array()) {
+		if (!is_string($file)) {
+			return false;
+		}
+
+		$matches = array();
+		$MagicFileResource =& new MagicFileResource($file);
+		foreach ($this->db['database'] as $format) {
+			$magic = $format[0];
+			$match = $MagicFileResource->test($magic);
+			if ($match === false) {
+				continue;
+			}
+			$matches[] = $magic;
+		}
+
+		return $matches;
+	}
+}
+
+/**
+ * undocumented class
+ *
+ * @package       cake.tests
+ * @subpackage    cake.tests.cases.libs
+ */
+class MagicFileResource extends Object{
+
+/**
+ * undocumented variable
+ *
+ * @var unknown
+ * @access public
+ */
+	var $resource = null;
+
+/**
+ * undocumented variable
+ *
+ * @var unknown
+ * @access public
+ */
+	var $offset = 0;
+
+/**
+ * undocumented function
+ *
+ * @param unknown $file
+ * @return void
+ * @access public
+ */
+	function __construct($file) {
+		if (file_exists($file)) {
+			$this->resource =& new File($file);
+		} else {
+			$this->resource = $file;
+		}
+	}
+
+/**
+ * undocumented function
+ *
+ * @param unknown $magic
+ * @return void
+ * @access public
+ */
+	function test($magic) {
+		$offset = null;
+		$type = null;
+		$expected = null;
+		$comment = null;
+		if (isset($magic[0])) {
+			$offset = $magic[0];
+		}
+		if (isset($magic[1])) {
+			$type = $magic[1];
+		}
+		if (isset($magic[2])) {
+			$expected = $magic[2];
+		}
+		if (isset($magic[3])) {
+			$comment = $magic[3];
+		}
+		$val = $this->extract($offset, $type, $expected);
+		return $val == $expected;
+	}
+
+/**
+ * undocumented function
+ *
+ * @param unknown $type
+ * @param unknown $length
+ * @return void
+ * @access public
+ */
+	function read($length = null) {
+		if (!is_object($this->resource)) {
+			return substr($this->resource, $this->offset, $length);
+		}
+		return $this->resource->read($length);
+	}
+
+/**
+ * undocumented function
+ *
+ * @param unknown $type
+ * @param unknown $expected
+ * @return void
+ * @access public
+ */
+	function extract($offset, $type, $expected) {
+		switch ($type) {
+			case 'string':
+				$this->offset($offset);
+				$val = $this->read(strlen($expected));
+				if ($val === $expected) {
+					return true;
+				}
+				break;
+		}
+	}
+
+/**
+ * undocumented function
+ *
+ * @param unknown $offset
+ * @param unknown $whence
+ * @return void
+ * @access public
+ */
+	function offset($offset = null) {
+		if (is_null($offset)) {
+			if (!is_object($this->resource)) {
+				return $this->offset;
+			}
+			return $this->offset;
+		}
+
+		if (!ctype_digit($offset)) {
+			return false;
+		}
+		if (is_object($this->resource)) {
+			$this->resource->offset($offset);
+		} else {
+			$this->offset = $offset;
+		}
+	}
+}