Bump version to 3.3.6
[kohana-core.git] / utf8 / substr.php
blobbf17dccf8e81a62b3a2b15583880764f5871f04f
1 <?php defined('SYSPATH') OR die('No direct script access.');
2 /**
3 * UTF8::substr
5 * @package Kohana
6 * @author Kohana Team
7 * @copyright (c) 2007-2012 Kohana Team
8 * @copyright (c) 2005 Harry Fuecks
9 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
11 function _substr($str, $offset, $length = NULL)
13 if (UTF8::is_ascii($str))
14 return ($length === NULL) ? substr($str, $offset) : substr($str, $offset, $length);
16 // Normalize params
17 $str = (string) $str;
18 $strlen = UTF8::strlen($str);
19 $offset = (int) ($offset < 0) ? max(0, $strlen + $offset) : $offset; // Normalize to positive offset
20 $length = ($length === NULL) ? NULL : (int) $length;
22 // Impossible
23 if ($length === 0 OR $offset >= $strlen OR ($length < 0 AND $length <= $offset - $strlen))
24 return '';
26 // Whole string
27 if ($offset == 0 AND ($length === NULL OR $length >= $strlen))
28 return $str;
30 // Build regex
31 $regex = '^';
33 // Create an offset expression
34 if ($offset > 0)
36 // PCRE repeating quantifiers must be less than 65536, so repeat when necessary
37 $x = (int) ($offset / 65535);
38 $y = (int) ($offset % 65535);
39 $regex .= ($x == 0) ? '' : ('(?:.{65535}){'.$x.'}');
40 $regex .= ($y == 0) ? '' : ('.{'.$y.'}');
43 // Create a length expression
44 if ($length === NULL)
46 $regex .= '(.*)'; // No length set, grab it all
48 // Find length from the left (positive length)
49 elseif ($length > 0)
51 // Reduce length so that it can't go beyond the end of the string
52 $length = min($strlen - $offset, $length);
54 $x = (int) ($length / 65535);
55 $y = (int) ($length % 65535);
56 $regex .= '(';
57 $regex .= ($x == 0) ? '' : ('(?:.{65535}){'.$x.'}');
58 $regex .= '.{'.$y.'})';
60 // Find length from the right (negative length)
61 else
63 $x = (int) (-$length / 65535);
64 $y = (int) (-$length % 65535);
65 $regex .= '(.*)';
66 $regex .= ($x == 0) ? '' : ('(?:.{65535}){'.$x.'}');
67 $regex .= '.{'.$y.'}';
70 preg_match('/'.$regex.'/us', $str, $matches);
71 return $matches[1];