PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/system/core/utf8/substr.php

https://github.com/lmorchard/friendfeedarchiver
PHP | 75 lines | 47 code | 9 blank | 19 comment | 11 complexity | 1d7c6af884938a6a4327b098daec1703 MD5 | raw file
  1. <?php defined('SYSPATH') or die('No direct script access.');
  2. /**
  3. * utf8::substr
  4. *
  5. * @package Core
  6. * @author Kohana Team
  7. * @copyright (c) 2007 Kohana Team
  8. * @copyright (c) 2005 Harry Fuecks
  9. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
  10. */
  11. function _substr($str, $offset, $length = NULL)
  12. {
  13. if (SERVER_UTF8)
  14. return ($length === NULL) ? mb_substr($str, $offset) : mb_substr($str, $offset, $length);
  15. if (utf8::is_ascii($str))
  16. return ($length === NULL) ? substr($str, $offset) : substr($str, $offset, $length);
  17. // Normalize params
  18. $str = (string) $str;
  19. $strlen = utf8::strlen($str);
  20. $offset = (int) ($offset < 0) ? max(0, $strlen + $offset) : $offset; // Normalize to positive offset
  21. $length = ($length === NULL) ? NULL : (int) $length;
  22. // Impossible
  23. if ($length === 0 OR $offset >= $strlen OR ($length < 0 AND $length <= $offset - $strlen))
  24. return '';
  25. // Whole string
  26. if ($offset == 0 AND ($length === NULL OR $length >= $strlen))
  27. return $str;
  28. // Build regex
  29. $regex = '^';
  30. // Create an offset expression
  31. if ($offset > 0)
  32. {
  33. // PCRE repeating quantifiers must be less than 65536, so repeat when necessary
  34. $x = (int) ($offset / 65535);
  35. $y = (int) ($offset % 65535);
  36. $regex .= ($x == 0) ? '' : '(?:.{65535}){'.$x.'}';
  37. $regex .= ($y == 0) ? '' : '.{'.$y.'}';
  38. }
  39. // Create a length expression
  40. if ($length === NULL)
  41. {
  42. $regex .= '(.*)'; // No length set, grab it all
  43. }
  44. // Find length from the left (positive length)
  45. elseif ($length > 0)
  46. {
  47. // Reduce length so that it can't go beyond the end of the string
  48. $length = min($strlen - $offset, $length);
  49. $x = (int) ($length / 65535);
  50. $y = (int) ($length % 65535);
  51. $regex .= '(';
  52. $regex .= ($x == 0) ? '' : '(?:.{65535}){'.$x.'}';
  53. $regex .= '.{'.$y.'})';
  54. }
  55. // Find length from the right (negative length)
  56. else
  57. {
  58. $x = (int) (-$length / 65535);
  59. $y = (int) (-$length % 65535);
  60. $regex .= '(.*)';
  61. $regex .= ($x == 0) ? '' : '(?:.{65535}){'.$x.'}';
  62. $regex .= '.{'.$y.'}';
  63. }
  64. preg_match('/'.$regex.'/us', $str, $matches);
  65. return $matches[1];
  66. }