magic_db.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: magic_db.php 7847 2008-11-08 02:54:07Z renan.saddam $ */
00003 /**
00004  * MagicDb parser and file analyzer
00005  *
00006  * PHP versions 4 and 5
00007  *
00008  * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
00009  * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00010  *
00011  * Licensed under The MIT License
00012  * Redistributions of files must retain the above copyright notice.
00013  *
00014  * @filesource
00015  * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00016  * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00017  * @package       cake
00018  * @subpackage    cake.cake.libs
00019  * @since         CakePHP(tm) v 1.2.0
00020  * @version       $Revision: 7847 $
00021  * @modifiedby    $LastChangedBy: renan.saddam $
00022  * @lastmodified  $Date: 2008-11-07 21:54:07 -0500 (Fri, 07 Nov 2008) $
00023  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
00024  */
00025 if (!class_exists('File')) {
00026     uses('object', 'file');
00027 }
00028 /**
00029  * A class to parse and use the MagicDb for file type analysis
00030  *
00031  * @package       cake.tests
00032  * @subpackage    cake.tests.cases.libs
00033  */
00034 class MagicDb extends Object {
00035 /**
00036  * Holds the parsed MagicDb for this class instance
00037  *
00038  * @var array
00039  **/
00040     var $db = array();
00041 
00042 /**
00043  * Reads a MagicDb from various formats
00044  *
00045  * @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
00046  * @return boolean Returns false if reading / validation failed or true on success.
00047  * @author        Felix
00048  **/
00049     function read($magicDb = null) {
00050         if (!is_string($magicDb) && !is_array($magicDb)) {
00051             return false;
00052         }
00053         if (is_array($magicDb) || strpos($magicDb, '# FILE_ID DB') === 0) {
00054             $data = $magicDb;
00055         } else {
00056             $File =& new File($magicDb);
00057             if (!$File->exists()) {
00058                 return false;
00059             }
00060             if ($File->ext() == 'php') {
00061                 include($File->pwd());
00062                 $data = $magicDb;
00063             } else {
00064                 // @TODO: Needs test coverage
00065                 $data = $File->read();
00066             }
00067         }
00068 
00069         $magicDb = $this->toArray($data);
00070         if (!$this->validates($magicDb)) {
00071             return false;
00072         }
00073         return !!($this->db = $magicDb);
00074     }
00075 
00076 /**
00077  * Parses a MagicDb $data string into an array or returns the current MagicDb instance as an array
00078  *
00079  * @param string $data A MagicDb string to turn into an array
00080  * @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.
00081  * @access public
00082  */
00083     function toArray($data = null) {
00084         if (is_array($data)) {
00085             return $data;
00086         }
00087         if ($data === null) {
00088             return $this->db;
00089         }
00090 
00091         if (strpos($data, '# FILE_ID DB') !== 0) {
00092             return array();
00093         }
00094 
00095         $lines = explode("\r\n", $data);
00096         $db = array();
00097 
00098         $validHeader = count($lines > 3)
00099                     && preg_match('/^# Date:([0-9]{4}-[0-9]{2}-[0-9]{2})$/', $lines[1], $date)
00100                     && preg_match('/^# Source:(.+)$/', $lines[2], $source)
00101                     && strlen($lines[3]) == 0;
00102         if (!$validHeader) {
00103             return $db;
00104         }
00105 
00106         $db = array('header' => array('Date' => $date[1], 'Source' => $source[1]), 'database' => array());
00107         $lines = array_splice($lines, 3);
00108 
00109         $format = array();
00110         while (!empty($lines)) {
00111             $line = array_shift($lines);
00112             if (isset($line[0]) && $line[0] == '#' || empty($line)) {
00113                 continue;
00114             }
00115 
00116             $columns = explode("\t", $line);
00117             if (in_array($columns[0]{0}, array('>', '&'))) {
00118                 $format[] = $columns;
00119             } elseif (!empty($format)) {
00120                 $db['database'][] = $format;
00121                 $format = array($columns);
00122             } else {
00123                 $format = array($columns);
00124             }
00125         }
00126 
00127         return $db;
00128     }
00129 
00130 /**
00131  * Returns true if the MagicDb instance or the passed $magicDb is valid
00132  *
00133  * @param mixed $magicDb A $magicDb string / array to validate (optional)
00134  * @return boolean True if the $magicDb / instance db validates, false if not
00135  * @access public
00136  */
00137     function validates($magicDb = null) {
00138         if (is_null($magicDb)) {
00139             $magicDb = $this->db;
00140         } elseif (!is_array($magicDb)) {
00141             $magicDb = $this->toArray($magicDb);
00142         }
00143 
00144         return isset($magicDb['header'], $magicDb['database']) && is_array($magicDb['header']) && is_array($magicDb['database']);
00145     }
00146 
00147 /**
00148  * Analyzes a given $file using the currently loaded MagicDb information based on the desired $options
00149  *
00150  * @param string $file Absolute path to the file to analyze
00151  * @param array $options TBT
00152  * @return mixed
00153  * @access public
00154  */
00155     function analyze($file, $options = array()) {
00156         if (!is_string($file)) {
00157             return false;
00158         }
00159 
00160         $matches = array();
00161         $MagicFileResource =& new MagicFileResource($file);
00162         foreach ($this->db['database'] as $format) {
00163             $magic = $format[0];
00164             $match = $MagicFileResource->test($magic);
00165             if ($match === false) {
00166                 continue;
00167             }
00168             $matches[] = $magic;
00169         }
00170 
00171         return $matches;
00172     }
00173 }
00174 
00175 /**
00176  * undocumented class
00177  *
00178  * @package       cake.tests
00179  * @subpackage    cake.tests.cases.libs
00180  */
00181 class MagicFileResource extends Object{
00182 /**
00183  * undocumented variable
00184  *
00185  * @var unknown
00186  * @access public
00187  */
00188     var $resource = null;
00189 /**
00190  * undocumented variable
00191  *
00192  * @var unknown
00193  * @access public
00194  */
00195     var $offset = 0;
00196 /**
00197  * undocumented function
00198  *
00199  * @param unknown $file
00200  * @return void
00201  * @access public
00202  */
00203     function __construct($file) {
00204         if (file_exists($file)) {
00205             $this->resource =& new File($file);
00206         } else {
00207             $this->resource = $file;
00208         }
00209     }
00210 /**
00211  * undocumented function
00212  *
00213  * @param unknown $magic
00214  * @return void
00215  * @access public
00216  */
00217     function test($magic) {
00218         $offset = null;
00219         $type = null;
00220         $expected = null;
00221         $comment = null;
00222         if (isset($magic[0])) {
00223             $offset = $magic[0];
00224         }
00225         if (isset($magic[1])) {
00226             $type = $magic[1];
00227         }
00228         if (isset($magic[2])) {
00229             $expected = $magic[2];
00230         }
00231         if (isset($magic[3])) {
00232             $comment = $magic[3];
00233         }
00234         $val = $this->extract($offset, $type, $expected);
00235         return $val == $expected;
00236     }
00237 /**
00238  * undocumented function
00239  *
00240  * @param unknown $type
00241  * @param unknown $length
00242  * @return void
00243  * @access public
00244  */
00245     function read($length = null) {
00246         if (!is_object($this->resource)) {
00247             return substr($this->resource, $this->offset, $length);
00248         }
00249         return $this->resource->read($length);
00250     }
00251 /**
00252  * undocumented function
00253  *
00254  * @param unknown $type
00255  * @param unknown $expected
00256  * @return void
00257  * @access public
00258  */
00259     function extract($offset, $type, $expected) {
00260         switch ($type) {
00261             case 'string':
00262                 $this->offset($offset);
00263                 $val = $this->read(strlen($expected));
00264                 if ($val === $expected) {
00265                     return true;
00266                 }
00267                 break;
00268         }
00269     }
00270 /**
00271  * undocumented function
00272  *
00273  * @param unknown $offset
00274  * @param unknown $whence
00275  * @return void
00276  * @access public
00277  */
00278     function offset($offset = null) {
00279         if (is_null($offset)) {
00280             if (!is_object($this->resource)) {
00281                 return $this->offset;
00282             }
00283             return $this->offset;
00284         }
00285 
00286         if (!ctype_digit($offset)) {
00287             return false;
00288         }
00289         if (is_object($this->resource)) {
00290             $this->resource->offset($offset);
00291         } else {
00292             $this->offset = $offset;
00293         }
00294     }
00295 }
00296 
00297 ?>

Generated on Sun Nov 22 00:30:53 2009 for CakePHP 1.2.x.x (v1.2.4.8284) by doxygen 1.4.7