Mercurial > hg > Members > shoshi > webvirt
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:261e66bd5a0c |
---|---|
1 <?php | |
2 /** | |
3 * MagicDb parser and file analyzer | |
4 * | |
5 * PHP versions 4 and 5 | |
6 * | |
7 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | |
8 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
9 * | |
10 * Licensed under The MIT License | |
11 * Redistributions of files must retain the above copyright notice. | |
12 * | |
13 * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
14 * @link http://cakephp.org CakePHP(tm) Project | |
15 * @package cake | |
16 * @subpackage cake.cake.libs | |
17 * @since CakePHP(tm) v 1.2.0 | |
18 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) | |
19 */ | |
20 if (!class_exists('Object')) { | |
21 require LIBS . 'object.php'; | |
22 } | |
23 if (!class_exists('File')) { | |
24 require LIBS . 'file.php'; | |
25 } | |
26 | |
27 /** | |
28 * A class to parse and use the MagicDb for file type analysis | |
29 * | |
30 * @package cake.tests | |
31 * @subpackage cake.tests.cases.libs | |
32 */ | |
33 class MagicDb extends Object { | |
34 | |
35 /** | |
36 * Holds the parsed MagicDb for this class instance | |
37 * | |
38 * @var array | |
39 */ | |
40 var $db = array(); | |
41 | |
42 /** | |
43 * Reads a MagicDb from various formats | |
44 * | |
45 * @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 | |
46 * @return boolean Returns false if reading / validation failed or true on success. | |
47 * @author Felix | |
48 */ | |
49 function read($magicDb = null) { | |
50 if (!is_string($magicDb) && !is_array($magicDb)) { | |
51 return false; | |
52 } | |
53 if (is_array($magicDb) || strpos($magicDb, '# FILE_ID DB') === 0) { | |
54 $data = $magicDb; | |
55 } else { | |
56 $File =& new File($magicDb); | |
57 if (!$File->exists()) { | |
58 return false; | |
59 } | |
60 if ($File->ext() == 'php') { | |
61 include($File->pwd()); | |
62 $data = $magicDb; | |
63 } else { | |
64 // @TODO: Needs test coverage | |
65 $data = $File->read(); | |
66 } | |
67 } | |
68 | |
69 $magicDb = $this->toArray($data); | |
70 if (!$this->validates($magicDb)) { | |
71 return false; | |
72 } | |
73 return !!($this->db = $magicDb); | |
74 } | |
75 | |
76 /** | |
77 * Parses a MagicDb $data string into an array or returns the current MagicDb instance as an array | |
78 * | |
79 * @param string $data A MagicDb string to turn into an array | |
80 * @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. | |
81 * @access public | |
82 */ | |
83 function toArray($data = null) { | |
84 if (is_array($data)) { | |
85 return $data; | |
86 } | |
87 if ($data === null) { | |
88 return $this->db; | |
89 } | |
90 | |
91 if (strpos($data, '# FILE_ID DB') !== 0) { | |
92 return array(); | |
93 } | |
94 | |
95 $lines = explode("\r\n", $data); | |
96 $db = array(); | |
97 | |
98 $validHeader = count($lines) > 3 | |
99 && preg_match('/^# Date:([0-9]{4}-[0-9]{2}-[0-9]{2})$/', $lines[1], $date) | |
100 && preg_match('/^# Source:(.+)$/', $lines[2], $source) | |
101 && strlen($lines[3]) == 0; | |
102 if (!$validHeader) { | |
103 return $db; | |
104 } | |
105 | |
106 $db = array('header' => array('Date' => $date[1], 'Source' => $source[1]), 'database' => array()); | |
107 $lines = array_splice($lines, 3); | |
108 | |
109 $format = array(); | |
110 while (!empty($lines)) { | |
111 $line = array_shift($lines); | |
112 if (isset($line[0]) && $line[0] == '#' || empty($line)) { | |
113 continue; | |
114 } | |
115 | |
116 $columns = explode("\t", $line); | |
117 if (in_array($columns[0]{0}, array('>', '&'))) { | |
118 $format[] = $columns; | |
119 } elseif (!empty($format)) { | |
120 $db['database'][] = $format; | |
121 $format = array($columns); | |
122 } else { | |
123 $format = array($columns); | |
124 } | |
125 } | |
126 | |
127 return $db; | |
128 } | |
129 | |
130 /** | |
131 * Returns true if the MagicDb instance or the passed $magicDb is valid | |
132 * | |
133 * @param mixed $magicDb A $magicDb string / array to validate (optional) | |
134 * @return boolean True if the $magicDb / instance db validates, false if not | |
135 * @access public | |
136 */ | |
137 function validates($magicDb = null) { | |
138 if (is_null($magicDb)) { | |
139 $magicDb = $this->db; | |
140 } elseif (!is_array($magicDb)) { | |
141 $magicDb = $this->toArray($magicDb); | |
142 } | |
143 | |
144 return isset($magicDb['header'], $magicDb['database']) && is_array($magicDb['header']) && is_array($magicDb['database']); | |
145 } | |
146 | |
147 /** | |
148 * Analyzes a given $file using the currently loaded MagicDb information based on the desired $options | |
149 * | |
150 * @param string $file Absolute path to the file to analyze | |
151 * @param array $options TBT | |
152 * @return mixed | |
153 * @access public | |
154 */ | |
155 function analyze($file, $options = array()) { | |
156 if (!is_string($file)) { | |
157 return false; | |
158 } | |
159 | |
160 $matches = array(); | |
161 $MagicFileResource =& new MagicFileResource($file); | |
162 foreach ($this->db['database'] as $format) { | |
163 $magic = $format[0]; | |
164 $match = $MagicFileResource->test($magic); | |
165 if ($match === false) { | |
166 continue; | |
167 } | |
168 $matches[] = $magic; | |
169 } | |
170 | |
171 return $matches; | |
172 } | |
173 } | |
174 | |
175 /** | |
176 * undocumented class | |
177 * | |
178 * @package cake.tests | |
179 * @subpackage cake.tests.cases.libs | |
180 */ | |
181 class MagicFileResource extends Object{ | |
182 | |
183 /** | |
184 * undocumented variable | |
185 * | |
186 * @var unknown | |
187 * @access public | |
188 */ | |
189 var $resource = null; | |
190 | |
191 /** | |
192 * undocumented variable | |
193 * | |
194 * @var unknown | |
195 * @access public | |
196 */ | |
197 var $offset = 0; | |
198 | |
199 /** | |
200 * undocumented function | |
201 * | |
202 * @param unknown $file | |
203 * @return void | |
204 * @access public | |
205 */ | |
206 function __construct($file) { | |
207 if (file_exists($file)) { | |
208 $this->resource =& new File($file); | |
209 } else { | |
210 $this->resource = $file; | |
211 } | |
212 } | |
213 | |
214 /** | |
215 * undocumented function | |
216 * | |
217 * @param unknown $magic | |
218 * @return void | |
219 * @access public | |
220 */ | |
221 function test($magic) { | |
222 $offset = null; | |
223 $type = null; | |
224 $expected = null; | |
225 $comment = null; | |
226 if (isset($magic[0])) { | |
227 $offset = $magic[0]; | |
228 } | |
229 if (isset($magic[1])) { | |
230 $type = $magic[1]; | |
231 } | |
232 if (isset($magic[2])) { | |
233 $expected = $magic[2]; | |
234 } | |
235 if (isset($magic[3])) { | |
236 $comment = $magic[3]; | |
237 } | |
238 $val = $this->extract($offset, $type, $expected); | |
239 return $val == $expected; | |
240 } | |
241 | |
242 /** | |
243 * undocumented function | |
244 * | |
245 * @param unknown $type | |
246 * @param unknown $length | |
247 * @return void | |
248 * @access public | |
249 */ | |
250 function read($length = null) { | |
251 if (!is_object($this->resource)) { | |
252 return substr($this->resource, $this->offset, $length); | |
253 } | |
254 return $this->resource->read($length); | |
255 } | |
256 | |
257 /** | |
258 * undocumented function | |
259 * | |
260 * @param unknown $type | |
261 * @param unknown $expected | |
262 * @return void | |
263 * @access public | |
264 */ | |
265 function extract($offset, $type, $expected) { | |
266 switch ($type) { | |
267 case 'string': | |
268 $this->offset($offset); | |
269 $val = $this->read(strlen($expected)); | |
270 if ($val === $expected) { | |
271 return true; | |
272 } | |
273 break; | |
274 } | |
275 } | |
276 | |
277 /** | |
278 * undocumented function | |
279 * | |
280 * @param unknown $offset | |
281 * @param unknown $whence | |
282 * @return void | |
283 * @access public | |
284 */ | |
285 function offset($offset = null) { | |
286 if (is_null($offset)) { | |
287 if (!is_object($this->resource)) { | |
288 return $this->offset; | |
289 } | |
290 return $this->offset; | |
291 } | |
292 | |
293 if (!ctype_digit($offset)) { | |
294 return false; | |
295 } | |
296 if (is_object($this->resource)) { | |
297 $this->resource->offset($offset); | |
298 } else { | |
299 $this->offset = $offset; | |
300 } | |
301 } | |
302 } |