Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 459 lines (414 sloc) 14.87 kb
e7f3c31 @gwoo going lithium
gwoo authored
1 <?php
2 /**
3 * Lithium: the most rad php framework
4 *
14de7bf @gwoo Happy 2012!
gwoo authored
5 * @copyright Copyright 2012, Union of RAD (http://union-of-rad.org)
238c504 @gwoo updating license and headers to give credit to our roots.
gwoo authored
6 * @license http://opensource.org/licenses/mit-license.php The MIT License
e7f3c31 @gwoo going lithium
gwoo authored
7 */
8
9 namespace lithium\util;
10
e5ab751 @nateabele Adding Windows fix for `\util\String::_source()`.
nateabele authored
11 use COM;
b7c93e9 @davidpersson QA: Removing leading backslash from classes in use statements.
davidpersson authored
12 use Closure;
13 use Exception;
ec44f52 @nateabele Refactoring `util\String` to clean up API and reduce method complexity.
nateabele authored
14
75bbe22 Adding class doc block.
psychic authored
15 /**
3cd874d @ddebernardy introduce \lithium\security\Crypto and \lithium\security\Password
ddebernardy authored
16 * String manipulation utility class. Includes functionality for generating UUIDs,
0e0c649 @nateabele Can't have `\util` dependencies outside of `\util` and `\core`. Moving `...
nateabele authored
17 * {:tag} and regex replacement, and tokenization. Also includes a cryptographically-strong random
18 * number generator, and a base64 encoder for use with DES and XDES.
75bbe22 Adding class doc block.
psychic authored
19 */
e7f3c31 @gwoo going lithium
gwoo authored
20 class String {
4081de0 @nateabele Reformatting `\util\String::uuid()` and associated constants.
nateabele authored
21
22 /**
23 * UUID-related constant. Clears all bits of version byte (`00001111`).
24 */
25 const UUID_CLEAR_VER = 15;
26
27 /**
28 * UUID constant that sets the version bit for generated UUIDs (`01000000`).
29 */
30 const UUID_VERSION_4 = 64;
31
8301ad2 @ddebernardy uuid improvements
ddebernardy authored
32 /**
4081de0 @nateabele Reformatting `\util\String::uuid()` and associated constants.
nateabele authored
33 * Clears relevant bits of variant byte (`00111111`).
8301ad2 @ddebernardy uuid improvements
ddebernardy authored
34 */
4081de0 @nateabele Reformatting `\util\String::uuid()` and associated constants.
nateabele authored
35 const UUID_CLEAR_VAR = 63;
36
37 /**
38 * The RFC 4122 variant (`10000000`).
39 */
40 const UUID_VAR_RFC = 128;
8301ad2 @ddebernardy uuid improvements
ddebernardy authored
41
42 /**
0e0c649 @nateabele Can't have `\util` dependencies outside of `\util` and `\core`. Moving `...
nateabele authored
43 * Option flag used in `String::random()`.
44 */
45 const ENCODE_BASE_64 = 1;
46
47 /**
48 * A closure which, given a number of bytes, returns that amount of
49 * random bytes.
50 *
51 * @var Closure
52 */
53 protected static $_source;
54
55 /**
6cd394e @ddebernardy move seed() out of random()
ddebernardy authored
56 * Generates an RFC 4122-compliant version 4 UUID.
bbd0964 @ddebernardy move rndom generator into its own function
ddebernardy authored
57 *
6cd394e @ddebernardy move seed() out of random()
ddebernardy authored
58 * @return string The string representation of an RFC 4122-compliant, version 4 UUID.
4081de0 @nateabele Reformatting `\util\String::uuid()` and associated constants.
nateabele authored
59 * @link http://www.ietf.org/rfc/rfc4122.txt RFC 4122: UUID URN Namespace
bbd0964 @ddebernardy move rndom generator into its own function
ddebernardy authored
60 */
61 public static function uuid() {
0e0c649 @nateabele Can't have `\util` dependencies outside of `\util` and `\core`. Moving `...
nateabele authored
62 $uuid = static::random(16);
4081de0 @nateabele Reformatting `\util\String::uuid()` and associated constants.
nateabele authored
63 $uuid[6] = chr(ord($uuid[6]) & static::UUID_CLEAR_VER | static::UUID_VERSION_4);
64 $uuid[8] = chr(ord($uuid[8]) & static::UUID_CLEAR_VAR | static::UUID_VAR_RFC);
bbd0964 @ddebernardy move rndom generator into its own function
ddebernardy authored
65
4081de0 @nateabele Reformatting `\util\String::uuid()` and associated constants.
nateabele authored
66 return join('-', array(
67 bin2hex(substr($uuid, 0, 4)),
68 bin2hex(substr($uuid, 4, 2)),
69 bin2hex(substr($uuid, 6, 2)),
70 bin2hex(substr($uuid, 8, 2)),
71 bin2hex(substr($uuid, 10, 6))
72 ));
e7f3c31 @gwoo going lithium
gwoo authored
73 }
74
75 /**
0e0c649 @nateabele Can't have `\util` dependencies outside of `\util` and `\core`. Moving `...
nateabele authored
76 * Generates random bytes for use in UUIDs and password salts, using
77 * (when available) a cryptographically strong random number generator.
78 *
79 * {{{
80 * $bits = String::random(8); // 64 bits
81 * $hex = bin2hex($bits); // [0-9a-f]+
82 * }}}
83 *
84 * Optionally base64-encodes the resulting random string per the following:
85 *
86 * _The alphabet used by `base64_encode()` is different than the one we should be using. When
87 * considering the meaty part of the resulting string, however, a bijection allows to go the
88 * from one to another. Given that we're working on random bytes, we can use safely use
89 * `base64_encode()` without losing any entropy._
90 *
91 * @param integer $bytes The number of random bytes to generate.
92 * @param array $options The options used when generating random bytes:
93 * - `'encode'` _integer_: If specified, and set to `String::ENCODE_BASE_64`, the
94 * resulting value will be base64-encoded, per the notes above.
95 * @return string Returns a string of random bytes.
96 */
97 public static function random($bytes, array $options = array()) {
98 $defaults = array('encode' => null);
99 $options += $defaults;
100
101 $source = static::$_source ?: static::_source();
102 $result = $source($bytes);
103
104 if ($options['encode'] != static::ENCODE_BASE_64) {
105 return $result;
106 }
107 return strtr(rtrim(base64_encode($result), '='), '+', '.');
108 }
109
110 /**
111 * Initializes `String::$_source` using the best available random number generator.
112 *
113 * When available, `/dev/urandom` and COM gets used on *nix and
114 * [Windows systems](http://msdn.microsoft.com/en-us/library/aa388182%28VS.85%29.aspx?ppud=4),
115 * respectively.
116 *
117 * If all else fails, a Mersenne Twister gets used. (Strictly
118 * speaking, this fallback is inadequate, but good enough.)
119 *
120 * @see lithium\util\String::$_source
121 * @return closure Returns a closure containing a random number generator.
122 */
123 protected static function _source() {
124 switch (true) {
125 case isset(static::$_source):
126 return static::$_source;
127 case is_readable('/dev/urandom') && $fp = fopen('/dev/urandom', 'rb'):
128 return static::$_source = function($bytes) use (&$fp) {
129 return fread($fp, $bytes);
130 };
e5ab751 @nateabele Adding Windows fix for `\util\String::_source()`.
nateabele authored
131 case class_exists('COM', false):
0e0c649 @nateabele Can't have `\util` dependencies outside of `\util` and `\core`. Moving `...
nateabele authored
132 try {
133 $com = new COM('CAPICOM.Utilities.1');
134 return static::$_source = function($bytes) use ($com) {
135 return base64_decode($com->GetRandom($bytes, 0));
136 };
137 } catch (Exception $e) {
138 }
139 default:
140 return static::$_source = function($bytes) {
141 $rand = '';
142
143 for ($i = 0; $i < $bytes; $i++) {
144 $rand .= chr(mt_rand(0, 255));
145 }
146 return $rand;
147 };
148 }
149 }
150
151 /**
152 * Uses PHP's hashing functions to create a hash of the string provided, using the options
153 * specified. The default hash algorithm is SHA-512.
73476ba @nateabele Making `\util\String::hash()` now throw an exception instead of forwardi...
nateabele authored
154 *
0e0c649 @nateabele Can't have `\util` dependencies outside of `\util` and `\core`. Moving `...
nateabele authored
155 * @link http://php.net/manual/en/function.hash.php PHP Manual: `hash()`
156 * @link http://php.net/manual/en/function.hash-hmac.php PHP Manual: `hash_hmac()`
157 * @link http://php.net/manual/en/function.hash-algos.php PHP Manual: `hash_algos()`
158 * @param string $string The string to hash.
159 * @param array $options Supported options:
160 * - `'type'` _string_: Any valid hashing algorithm. See the `hash_algos()` function to
161 * determine which are available on your system.
162 * - `'salt'` _string_: A _salt_ value which, if specified, will be prepended to the
163 * string.
164 * - `'key'` _string_: If specified `hash_hmac()` will be used to hash the string,
165 * instead of `hash()`, with `'key'` being used as the message key.
166 * - `'raw'` _boolean_: If `true`, outputs the raw binary result of the hash operation.
167 * Defaults to `false`.
168 * @return string Returns a hashed string.
e7f3c31 @gwoo going lithium
gwoo authored
169 */
1365201 @Howard3 Updated String::hash and it's test
Howard3 authored
170 public static function hash($string, array $options = array()) {
0e0c649 @nateabele Can't have `\util` dependencies outside of `\util` and `\core`. Moving `...
nateabele authored
171 $defaults = array(
172 'type' => 'sha512',
173 'salt' => false,
174 'key' => false,
26c2192 @davidpersson QA: Removing trailing comma in arrays, lowercasing some keywords.
davidpersson authored
175 'raw' => false
0e0c649 @nateabele Can't have `\util` dependencies outside of `\util` and `\core`. Moving `...
nateabele authored
176 );
177 $options += $defaults;
178
179 if ($options['salt']) {
180 $string = $options['salt'] . $string;
181 }
182 if ($options['key']) {
183 return hash_hmac($options['type'], $string, $options['key'], $options['raw']);
184 }
185 return hash($options['type'], $string, $options['raw']);
e7f3c31 @gwoo going lithium
gwoo authored
186 }
187
188 /**
3b376e6 @daschl Security: Refactoring timing attack prevention into String class and imp...
daschl authored
189 * Compares two strings in constant time to prevent timing attacks.
190 *
191 * @link http://codahale.com/a-lesson-in-timing-attacks/ More about timing attacks.
192 * @param string $left The left side of the comparison.
193 * @param string $right The right side of the comparison.
194 * @return boolean Returns a boolean indicating whether the two strings are equal.
195 */
0ac200f @daschl Security: Renaming compareConstant to compare
daschl authored
196 public static function compare($left, $right) {
3b376e6 @daschl Security: Refactoring timing attack prevention into String class and imp...
daschl authored
197 $result = true;
198
199 if (($length = strlen($left)) != strlen($right)) {
200 return false;
201 }
202 for ($i = 0; $i < $length; $i++) {
203 $result = $result && ($left[$i] === $right[$i]);
204 }
205 return $result;
206 }
207
208 /**
9562780 @niel Typo, spelling, and punctuation fixes.
niel authored
209 * Replaces variable placeholders inside a string with any given data. Each key
210 * in the `$data` array corresponds to a variable placeholder name in `$str`.
e7f3c31 @gwoo going lithium
gwoo authored
211 *
b8d0b06 @davidpersson Updating docblocks of String.
davidpersson authored
212 * Usage:
e7f3c31 @gwoo going lithium
gwoo authored
213 * {{{
214 * String::insert(
215 * 'My name is {:name} and I am {:age} years old.',
216 * array('name' => 'Bob', 'age' => '65')
b8d0b06 @davidpersson Updating docblocks of String.
davidpersson authored
217 * ); // returns 'My name is Bob and I am 65 years old.'
e7f3c31 @gwoo going lithium
gwoo authored
218 * }}}
219 *
a102fe6 @niel Adding/fixing doc blocks for methods clean(), hash(), insert(), and uuid...
niel authored
220 * @param string $str A string containing variable place-holders.
97c5e7c @Howard3 Doing a general QA and Docblock
Howard3 authored
221 * @param array $data A key, value array where each key stands for a place-holder variable
b8d0b06 @davidpersson Updating docblocks of String.
davidpersson authored
222 * name to be replaced with value.
97c5e7c @Howard3 Doing a general QA and Docblock
Howard3 authored
223 * @param array $options Available options are:
a102fe6 @niel Adding/fixing doc blocks for methods clean(), hash(), insert(), and uuid...
niel authored
224 * - `'after'`: The character or string after the name of the variable place-holder
225be23 @davidpersson Synchronize documented defaults in `String::insert()`.
davidpersson authored
225 * (defaults to `}`).
8de98e9 @nateabele Fixing coding standards violations. Closes ticket #143.
nateabele authored
226 * - `'before'`: The character or string in front of the name of the variable
225be23 @davidpersson Synchronize documented defaults in `String::insert()`.
davidpersson authored
227 * place-holder (defaults to `'{:'`).
a102fe6 @niel Adding/fixing doc blocks for methods clean(), hash(), insert(), and uuid...
niel authored
228 * - `'clean'`: A boolean or array with instructions for `String::clean()`.
229 * - `'escape'`: The character or string used to escape the before character or string
230 * (defaults to `'\'`).
231 * - `'format'`: A regular expression to use for matching variable place-holders
232 * (defaults to `'/(?<!\\)\:%s/'`. Please note that this option takes precedence over
233 * all other options except `'clean'`.
e7f3c31 @gwoo going lithium
gwoo authored
234 * @return string
b8d0b06 @davidpersson Updating docblocks of String.
davidpersson authored
235 * @todo Optimize this
e7f3c31 @gwoo going lithium
gwoo authored
236 */
0abd905 @nateabele Removing unused variables in `\template\Helper`, optimizing default exec...
nateabele authored
237 public static function insert($str, array $data, array $options = array()) {
e7f3c31 @gwoo going lithium
gwoo authored
238 $defaults = array(
0abd905 @nateabele Removing unused variables in `\template\Helper`, optimizing default exec...
nateabele authored
239 'before' => '{:',
240 'after' => '}',
241 'escape' => null,
242 'format' => null,
26c2192 @davidpersson QA: Removing trailing comma in arrays, lowercasing some keywords.
davidpersson authored
243 'clean' => false
e7f3c31 @gwoo going lithium
gwoo authored
244 );
245 $options += $defaults;
246 $format = $options['format'];
9f0bace @nateabele Fixing optimization case in `\util\String::insert()`.
nateabele authored
247 reset($data);
e7f3c31 @gwoo going lithium
gwoo authored
248
ba8f337 @nateabele Refactoring `\util\String::tokenize()` to reduce nesting.
nateabele authored
249 if ($format == 'regex' || (!$format && $options['escape'])) {
e7f3c31 @gwoo going lithium
gwoo authored
250 $format = sprintf(
251 '/(?<!%s)%s%%s%s/',
252 preg_quote($options['escape'], '/'),
253 str_replace('%', '%%', preg_quote($options['before'], '/')),
254 str_replace('%', '%%', preg_quote($options['after'], '/'))
255 );
256 }
257
ba8f337 @nateabele Refactoring `\util\String::tokenize()` to reduce nesting.
nateabele authored
258 if (!$format && key($data) !== 0) {
e7f3c31 @gwoo going lithium
gwoo authored
259 $replace = array();
260
261 foreach ($data as $key => $value) {
0a20c0b @nateabele Refactoring `Form` helper string templates to use wrapping instead of st...
nateabele authored
262 $value = (is_array($value) || $value instanceof Closure) ? '' : $value;
263
264 try {
265 if (is_object($value) && method_exists($value, '__toString')) {
266 $value = (string) $value;
267 }
268 } catch (Exception $e) {
269 $value = '';
270 }
e7f3c31 @gwoo going lithium
gwoo authored
271 $replace["{$options['before']}{$key}{$options['after']}"] = $value;
272 }
273 $str = strtr($str, $replace);
274 return $options['clean'] ? static::clean($str, $options) : $str;
275 }
276
588ff1b @gwoo fix for String::insert() when ? in the string.
gwoo authored
277 if (strpos($str, '?') !== false && isset($data[0])) {
e7f3c31 @gwoo going lithium
gwoo authored
278 $offset = 0;
279 while (($pos = strpos($str, '?', $offset)) !== false) {
280 $val = array_shift($data);
281 $offset = $pos + strlen($val);
282 $str = substr_replace($str, $val, $pos, 1);
283 }
284 return $options['clean'] ? static::clean($str, $options) : $str;
285 }
286
287 foreach ($data as $key => $value) {
288 $hashVal = crc32($key);
289 $key = sprintf($format, preg_quote($key, '/'));
588ff1b @gwoo fix for String::insert() when ? in the string.
gwoo authored
290
291 if (!$key) {
292 continue;
293 }
e7f3c31 @gwoo going lithium
gwoo authored
294 $str = preg_replace($key, $hashVal, $str);
8c4078a @nateabele Fixing an issue in `\util\String::insert()` where empty values (i.e. 0) ...
nateabele authored
295 $str = str_replace($hashVal, $value, $str);
e7f3c31 @gwoo going lithium
gwoo authored
296 }
297
298 if (!isset($options['format']) && isset($options['before'])) {
299 $str = str_replace($options['escape'] . $options['before'], $options['before'], $str);
300 }
301 return $options['clean'] ? static::clean($str, $options) : $str;
302 }
303
304 /**
a102fe6 @niel Adding/fixing doc blocks for methods clean(), hash(), insert(), and uuid...
niel authored
305 * Cleans up a `Set::insert()` formatted string with given `$options` depending
b8d0b06 @davidpersson Updating docblocks of String.
davidpersson authored
306 * on the `'clean'` option. The goal of this function is to replace all whitespace
a102fe6 @niel Adding/fixing doc blocks for methods clean(), hash(), insert(), and uuid...
niel authored
307 * and unneeded mark-up around place-holders that did not get replaced by `Set::insert()`.
e7f3c31 @gwoo going lithium
gwoo authored
308 *
b8d0b06 @davidpersson Updating docblocks of String.
davidpersson authored
309 * @param string $str The string to clean.
97c5e7c @Howard3 Doing a general QA and Docblock
Howard3 authored
310 * @param array $options Available options are:
a102fe6 @niel Adding/fixing doc blocks for methods clean(), hash(), insert(), and uuid...
niel authored
311 * - `'after'`: characters marking the end of targeted substring.
312 * - `'andText'`: (defaults to `true`).
313 * - `'before'`: characters marking the start of targeted substring.
314 * - `'clean'`: `true` or an array of clean options:
315 * - `'gap'`: Regular expression matching gaps.
316 * - `'method'`: Either `'text'` or `'html'` (defaults to `'text'`).
317 * - `'replacement'`: String to use for cleaned substrings (defaults to `''`).
318 * - `'word'`: Regular expression matching words.
b8d0b06 @davidpersson Updating docblocks of String.
davidpersson authored
319 * @return string The cleaned string.
e7f3c31 @gwoo going lithium
gwoo authored
320 */
f80098d @nateabele Adding type hinting to constructor `$config` arrays and all applicable `...
nateabele authored
321 public static function clean($str, array $options = array()) {
e7f3c31 @gwoo going lithium
gwoo authored
322 if (!$options['clean']) {
323 return $str;
324 }
325 $clean = $options['clean'];
326 $clean = ($clean === true) ? array('method' => 'text') : $clean;
327 $clean = (!is_array($clean)) ? array('method' => $options['clean']) : $clean;
328
329 switch ($clean['method']) {
330 case 'html':
331 $clean += array('word' => '[\w,.]+', 'andText' => true, 'replacement' => '');
332 $kleenex = sprintf(
333 '/[\s]*[a-z]+=(")(%s%s%s[\s]*)+\\1/i',
334 preg_quote($options['before'], '/'),
335 $clean['word'],
336 preg_quote($options['after'], '/')
337 );
338 $str = preg_replace($kleenex, $clean['replacement'], $str);
339
340 if ($clean['andText']) {
341 $options['clean'] = array('method' => 'text');
342 $str = static::clean($str, $options);
343 }
344 break;
345 case 'text':
346 $clean += array(
347 'word' => '[\w,.]+', 'gap' => '[\s]*(?:(?:and|or|,)[\s]*)?', 'replacement' => ''
348 );
349 $before = preg_quote($options['before'], '/');
350 $after = preg_quote($options['after'], '/');
351
352 $kleenex = sprintf(
353 '/(%s%s%s%s|%s%s%s%s|%s%s%s%s%s)/',
354 $before, $clean['word'], $after, $clean['gap'],
355 $clean['gap'], $before, $clean['word'], $after,
356 $clean['gap'], $before, $clean['word'], $after, $clean['gap']
357 );
358 $str = preg_replace($kleenex, $clean['replacement'], $str);
359 break;
360 }
361 return $str;
362 }
b8d0b06 @davidpersson Updating docblocks of String.
davidpersson authored
363
e7f3c31 @gwoo going lithium
gwoo authored
364 /**
b8d0b06 @davidpersson Updating docblocks of String.
davidpersson authored
365 * Extract a part of a string based on a regular expression `$regex`.
e7f3c31 @gwoo going lithium
gwoo authored
366 *
b8d0b06 @davidpersson Updating docblocks of String.
davidpersson authored
367 * @param string $regex The regular expression to use.
368 * @param string $str The string to run the extraction on.
369 * @param integer $index The number of the part to return based on the regex.
e7f3c31 @gwoo going lithium
gwoo authored
370 * @return mixed
371 */
df87026 @nateabele Committing initial draft of `Auth` API, refactoring `Adaptable`, fixing ...
nateabele authored
372 public static function extract($regex, $str, $index = 0) {
e7f3c31 @gwoo going lithium
gwoo authored
373 if (!preg_match($regex, $str, $match)) {
374 return false;
375 }
376 return isset($match[$index]) ? $match[$index] : null;
377 }
378
379 /**
ba8f337 @nateabele Refactoring `\util\String::tokenize()` to reduce nesting.
nateabele authored
380 * Tokenizes a string using `$options['separator']`, ignoring any instances of
381 * `$options['separator']` that appear between `$options['leftBound']` and
ec44f52 @nateabele Refactoring `util\String` to clean up API and reduce method complexity.
nateabele authored
382 * `$options['rightBound']`.
e7f3c31 @gwoo going lithium
gwoo authored
383 *
b8d0b06 @davidpersson Updating docblocks of String.
davidpersson authored
384 * @param string $data The data to tokenize.
ec44f52 @nateabele Refactoring `util\String` to clean up API and reduce method complexity.
nateabele authored
385 * @param array $options Options to use when tokenizing:
386 * -`'separator'` _string_: The token to split the data on.
387 * -`'leftBound'` _string_: Left scope-enclosing boundary.
388 * -`'rightBound'` _string_: Right scope-enclosing boundary.
389 * @return array Returns an array of tokens.
e7f3c31 @gwoo going lithium
gwoo authored
390 */
f80098d @nateabele Adding type hinting to constructor `$config` arrays and all applicable `...
nateabele authored
391 public static function tokenize($data, array $options = array()) {
ec44f52 @nateabele Refactoring `util\String` to clean up API and reduce method complexity.
nateabele authored
392 $defaults = array('separator' => ',', 'leftBound' => '(', 'rightBound' => ')');
393 extract($options + $defaults);
394
ba8f337 @nateabele Refactoring `\util\String::tokenize()` to reduce nesting.
nateabele authored
395 if (!$data || is_array($data)) {
e7f3c31 @gwoo going lithium
gwoo authored
396 return $data;
397 }
398
399 $depth = 0;
400 $offset = 0;
401 $buffer = '';
402 $results = array();
403 $length = strlen($data);
404 $open = false;
405
406 while ($offset <= $length) {
407 $tmpOffset = -1;
408 $offsets = array(
409 strpos($data, $separator, $offset),
410 strpos($data, $leftBound, $offset),
411 strpos($data, $rightBound, $offset)
412 );
ba8f337 @nateabele Refactoring `\util\String::tokenize()` to reduce nesting.
nateabele authored
413
e7f3c31 @gwoo going lithium
gwoo authored
414 for ($i = 0; $i < 3; $i++) {
415 if ($offsets[$i] !== false && ($offsets[$i] < $tmpOffset || $tmpOffset == -1)) {
416 $tmpOffset = $offsets[$i];
417 }
418 }
ba8f337 @nateabele Refactoring `\util\String::tokenize()` to reduce nesting.
nateabele authored
419
420 if ($tmpOffset === -1) {
421 $results[] = $buffer . substr($data, $offset);
422 $offset = $length + 1;
423 continue;
424 }
425 $buffer .= substr($data, $offset, ($tmpOffset - $offset));
426
427 if ($data{$tmpOffset} == $separator && $depth == 0) {
428 $results[] = $buffer;
429 $buffer = '';
430 } else {
431 $buffer .= $data{$tmpOffset};
432 }
433
434 if ($leftBound != $rightBound) {
435 if ($data{$tmpOffset} == $leftBound) {
436 $depth++;
e7f3c31 @gwoo going lithium
gwoo authored
437 }
ba8f337 @nateabele Refactoring `\util\String::tokenize()` to reduce nesting.
nateabele authored
438 if ($data{$tmpOffset} == $rightBound) {
439 $depth--;
e7f3c31 @gwoo going lithium
gwoo authored
440 }
441 $offset = ++$tmpOffset;
ba8f337 @nateabele Refactoring `\util\String::tokenize()` to reduce nesting.
nateabele authored
442 continue;
443 }
444
445 if ($data{$tmpOffset} == $leftBound) {
446 ($open) ? $depth-- : $depth++;
447 $open = !$open;
e7f3c31 @gwoo going lithium
gwoo authored
448 }
ba8f337 @nateabele Refactoring `\util\String::tokenize()` to reduce nesting.
nateabele authored
449 $offset = ++$tmpOffset;
e7f3c31 @gwoo going lithium
gwoo authored
450 }
451
ba8f337 @nateabele Refactoring `\util\String::tokenize()` to reduce nesting.
nateabele authored
452 if (!$results && $buffer) {
e7f3c31 @gwoo going lithium
gwoo authored
453 $results[] = $buffer;
454 }
ba8f337 @nateabele Refactoring `\util\String::tokenize()` to reduce nesting.
nateabele authored
455 return $results ? array_map('trim', $results) : array();
e7f3c31 @gwoo going lithium
gwoo authored
456 }
457 }
458
459 ?>
Something went wrong with that request. Please try again.