/[web]/fidd/lib/fabpot-yaml/lib/sfYamlInline.php
ViewVC logotype

Contents of /fidd/lib/fabpot-yaml/lib/sfYamlInline.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1081 - (show annotations) (download)
Mon May 14 09:16:32 2012 UTC (11 years, 10 months ago) by rda
File size: 11515 byte(s)
add library and var dir
1 <?php
2
3 /*
4 * This file is part of the symfony package.
5 * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11 require_once dirname(__FILE__).'/sfYaml.php';
12
13 /**
14 * sfYamlInline implements a YAML parser/dumper for the YAML inline syntax.
15 *
16 * @package symfony
17 * @subpackage yaml
18 * @author Fabien Potencier <fabien.potencier@symfony-project.com>
19 * @version SVN: $Id: sfYamlInline.class.php 16177 2009-03-11 08:32:48Z fabien $
20 */
21 class sfYamlInline
22 {
23 const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
24
25 /**
26 * Convert a YAML string to a PHP array.
27 *
28 * @param string $value A YAML string
29 *
30 * @return array A PHP array representing the YAML string
31 */
32 static public function load($value)
33 {
34 $value = trim($value);
35
36 if (0 == strlen($value))
37 {
38 return '';
39 }
40
41 if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2)
42 {
43 $mbEncoding = mb_internal_encoding();
44 mb_internal_encoding('ASCII');
45 }
46
47 switch ($value[0])
48 {
49 case '[':
50 $result = self::parseSequence($value);
51 break;
52 case '{':
53 $result = self::parseMapping($value);
54 break;
55 default:
56 $result = self::parseScalar($value);
57 }
58
59 if (isset($mbEncoding))
60 {
61 mb_internal_encoding($mbEncoding);
62 }
63
64 return $result;
65 }
66
67 /**
68 * Dumps a given PHP variable to a YAML string.
69 *
70 * @param mixed $value The PHP variable to convert
71 *
72 * @return string The YAML string representing the PHP array
73 */
74 static public function dump($value)
75 {
76 if ('1.1' === sfYaml::getSpecVersion())
77 {
78 $trueValues = array('true', 'on', '+', 'yes', 'y');
79 $falseValues = array('false', 'off', '-', 'no', 'n');
80 }
81 else
82 {
83 $trueValues = array('true');
84 $falseValues = array('false');
85 }
86
87 switch (true)
88 {
89 case is_resource($value):
90 throw new InvalidArgumentException('Unable to dump PHP resources in a YAML file.');
91 case is_object($value):
92 return '!!php/object:'.serialize($value);
93 case is_array($value):
94 return self::dumpArray($value);
95 case null === $value:
96 return 'null';
97 case true === $value:
98 return 'true';
99 case false === $value:
100 return 'false';
101 case ctype_digit($value):
102 return is_string($value) ? "'$value'" : (int) $value;
103 case is_numeric($value):
104 return is_infinite($value) ? str_ireplace('INF', '.Inf', strval($value)) : (is_string($value) ? "'$value'" : $value);
105 case false !== strpos($value, "\n") || false !== strpos($value, "\r"):
106 return sprintf('"%s"', str_replace(array('"', "\n", "\r"), array('\\"', '\n', '\r'), $value));
107 case preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ - ? | < > = ! % @ ` ]/x', $value):
108 return sprintf("'%s'", str_replace('\'', '\'\'', $value));
109 case '' == $value:
110 return "''";
111 case preg_match(self::getTimestampRegex(), $value):
112 return "'$value'";
113 case in_array(strtolower($value), $trueValues):
114 return "'$value'";
115 case in_array(strtolower($value), $falseValues):
116 return "'$value'";
117 case in_array(strtolower($value), array('null', '~')):
118 return "'$value'";
119 default:
120 return $value;
121 }
122 }
123
124 /**
125 * Dumps a PHP array to a YAML string.
126 *
127 * @param array $value The PHP array to dump
128 *
129 * @return string The YAML string representing the PHP array
130 */
131 static protected function dumpArray($value)
132 {
133 // array
134 $keys = array_keys($value);
135 if (
136 (1 == count($keys) && '0' == $keys[0])
137 ||
138 (count($keys) > 1 && array_reduce($keys, create_function('$v,$w', 'return (integer) $v + $w;'), 0) == count($keys) * (count($keys) - 1) / 2))
139 {
140 $output = array();
141 foreach ($value as $val)
142 {
143 $output[] = self::dump($val);
144 }
145
146 return sprintf('[%s]', implode(', ', $output));
147 }
148
149 // mapping
150 $output = array();
151 foreach ($value as $key => $val)
152 {
153 $output[] = sprintf('%s: %s', self::dump($key), self::dump($val));
154 }
155
156 return sprintf('{ %s }', implode(', ', $output));
157 }
158
159 /**
160 * Parses a scalar to a YAML string.
161 *
162 * @param scalar $scalar
163 * @param string $delimiters
164 * @param array $stringDelimiter
165 * @param integer $i
166 * @param boolean $evaluate
167 *
168 * @return string A YAML string
169 */
170 static public function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true)
171 {
172 if (in_array($scalar[$i], $stringDelimiters))
173 {
174 // quoted scalar
175 $output = self::parseQuotedScalar($scalar, $i);
176 }
177 else
178 {
179 // "normal" string
180 if (!$delimiters)
181 {
182 $output = substr($scalar, $i);
183 $i += strlen($output);
184
185 // remove comments
186 if (false !== $strpos = strpos($output, ' #'))
187 {
188 $output = rtrim(substr($output, 0, $strpos));
189 }
190 }
191 else if (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match))
192 {
193 $output = $match[1];
194 $i += strlen($output);
195 }
196 else
197 {
198 throw new InvalidArgumentException(sprintf('Malformed inline YAML string (%s).', $scalar));
199 }
200
201 $output = $evaluate ? self::evaluateScalar($output) : $output;
202 }
203
204 return $output;
205 }
206
207 /**
208 * Parses a quoted scalar to YAML.
209 *
210 * @param string $scalar
211 * @param integer $i
212 *
213 * @return string A YAML string
214 */
215 static protected function parseQuotedScalar($scalar, &$i)
216 {
217 if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match))
218 {
219 throw new InvalidArgumentException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i)));
220 }
221
222 $output = substr($match[0], 1, strlen($match[0]) - 2);
223
224 if ('"' == $scalar[$i])
225 {
226 // evaluate the string
227 $output = str_replace(array('\\"', '\\n', '\\r'), array('"', "\n", "\r"), $output);
228 }
229 else
230 {
231 // unescape '
232 $output = str_replace('\'\'', '\'', $output);
233 }
234
235 $i += strlen($match[0]);
236
237 return $output;
238 }
239
240 /**
241 * Parses a sequence to a YAML string.
242 *
243 * @param string $sequence
244 * @param integer $i
245 *
246 * @return string A YAML string
247 */
248 static protected function parseSequence($sequence, &$i = 0)
249 {
250 $output = array();
251 $len = strlen($sequence);
252 $i += 1;
253
254 // [foo, bar, ...]
255 while ($i < $len)
256 {
257 switch ($sequence[$i])
258 {
259 case '[':
260 // nested sequence
261 $output[] = self::parseSequence($sequence, $i);
262 break;
263 case '{':
264 // nested mapping
265 $output[] = self::parseMapping($sequence, $i);
266 break;
267 case ']':
268 return $output;
269 case ',':
270 case ' ':
271 break;
272 default:
273 $isQuoted = in_array($sequence[$i], array('"', "'"));
274 $value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i);
275
276 if (!$isQuoted && false !== strpos($value, ': '))
277 {
278 // embedded mapping?
279 try
280 {
281 $value = self::parseMapping('{'.$value.'}');
282 }
283 catch (InvalidArgumentException $e)
284 {
285 // no, it's not
286 }
287 }
288
289 $output[] = $value;
290
291 --$i;
292 }
293
294 ++$i;
295 }
296
297 throw new InvalidArgumentException(sprintf('Malformed inline YAML string %s', $sequence));
298 }
299
300 /**
301 * Parses a mapping to a YAML string.
302 *
303 * @param string $mapping
304 * @param integer $i
305 *
306 * @return string A YAML string
307 */
308 static protected function parseMapping($mapping, &$i = 0)
309 {
310 $output = array();
311 $len = strlen($mapping);
312 $i += 1;
313
314 // {foo: bar, bar:foo, ...}
315 while ($i < $len)
316 {
317 switch ($mapping[$i])
318 {
319 case ' ':
320 case ',':
321 ++$i;
322 continue 2;
323 case '}':
324 return $output;
325 }
326
327 // key
328 $key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false);
329
330 // value
331 $done = false;
332 while ($i < $len)
333 {
334 switch ($mapping[$i])
335 {
336 case '[':
337 // nested sequence
338 $output[$key] = self::parseSequence($mapping, $i);
339 $done = true;
340 break;
341 case '{':
342 // nested mapping
343 $output[$key] = self::parseMapping($mapping, $i);
344 $done = true;
345 break;
346 case ':':
347 case ' ':
348 break;
349 default:
350 $output[$key] = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i);
351 $done = true;
352 --$i;
353 }
354
355 ++$i;
356
357 if ($done)
358 {
359 continue 2;
360 }
361 }
362 }
363
364 throw new InvalidArgumentException(sprintf('Malformed inline YAML string %s', $mapping));
365 }
366
367 /**
368 * Evaluates scalars and replaces magic values.
369 *
370 * @param string $scalar
371 *
372 * @return string A YAML string
373 */
374 static protected function evaluateScalar($scalar)
375 {
376 $scalar = trim($scalar);
377
378 if ('1.1' === sfYaml::getSpecVersion())
379 {
380 $trueValues = array('true', 'on', '+', 'yes', 'y');
381 $falseValues = array('false', 'off', '-', 'no', 'n');
382 }
383 else
384 {
385 $trueValues = array('true');
386 $falseValues = array('false');
387 }
388
389 switch (true)
390 {
391 case 'null' == strtolower($scalar):
392 case '' == $scalar:
393 case '~' == $scalar:
394 return null;
395 case 0 === strpos($scalar, '!str'):
396 return (string) substr($scalar, 5);
397 case 0 === strpos($scalar, '! '):
398 return intval(self::parseScalar(substr($scalar, 2)));
399 case 0 === strpos($scalar, '!!php/object:'):
400 return unserialize(substr($scalar, 13));
401 case ctype_digit($scalar):
402 $raw = $scalar;
403 $cast = intval($scalar);
404 return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
405 case in_array(strtolower($scalar), $trueValues):
406 return true;
407 case in_array(strtolower($scalar), $falseValues):
408 return false;
409 case is_numeric($scalar):
410 return '0x' == $scalar[0].$scalar[1] ? hexdec($scalar) : floatval($scalar);
411 case 0 == strcasecmp($scalar, '.inf'):
412 case 0 == strcasecmp($scalar, '.NaN'):
413 return -log(0);
414 case 0 == strcasecmp($scalar, '-.inf'):
415 return log(0);
416 case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
417 return floatval(str_replace(',', '', $scalar));
418 case preg_match(self::getTimestampRegex(), $scalar):
419 return strtotime($scalar);
420 default:
421 return (string) $scalar;
422 }
423 }
424
425 static protected function getTimestampRegex()
426 {
427 return <<<EOF
428 ~^
429 (?P<year>[0-9][0-9][0-9][0-9])
430 -(?P<month>[0-9][0-9]?)
431 -(?P<day>[0-9][0-9]?)
432 (?:(?:[Tt]|[ \t]+)
433 (?P<hour>[0-9][0-9]?)
434 :(?P<minute>[0-9][0-9])
435 :(?P<second>[0-9][0-9])
436 (?:\.(?P<fraction>[0-9]*))?
437 (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
438 (?::(?P<tz_minute>[0-9][0-9]))?))?)?
439 $~x
440 EOF;
441 }
442 }

  ViewVC Help
Powered by ViewVC 1.1.30