MediaWiki  REL1_24
Fallback.php
Go to the documentation of this file.
00001 <?php
00026 class Fallback {
00027 
00044     public static function mb_substr( $str, $start, $count = 'end' ) {
00045         if ( $start != 0 ) {
00046             $split = self::mb_substr_split_unicode( $str, intval( $start ) );
00047             $str = substr( $str, $split );
00048         }
00049 
00050         if ( $count !== 'end' ) {
00051             $split = self::mb_substr_split_unicode( $str, intval( $count ) );
00052             $str = substr( $str, 0, $split );
00053         }
00054 
00055         return $str;
00056     }
00057 
00063     public static function mb_substr_split_unicode( $str, $splitPos ) {
00064         if ( $splitPos == 0 ) {
00065             return 0;
00066         }
00067 
00068         $byteLen = strlen( $str );
00069 
00070         if ( $splitPos > 0 ) {
00071             if ( $splitPos > 256 ) {
00072                 // Optimize large string offsets by skipping ahead N bytes.
00073                 // This will cut out most of our slow time on Latin-based text,
00074                 // and 1/2 to 1/3 on East European and Asian scripts.
00075                 $bytePos = $splitPos;
00076                 while ( $bytePos < $byteLen && $str[$bytePos] >= "\x80" && $str[$bytePos] < "\xc0" ) {
00077                     ++$bytePos;
00078                 }
00079                 $charPos = mb_strlen( substr( $str, 0, $bytePos ) );
00080             } else {
00081                 $charPos = 0;
00082                 $bytePos = 0;
00083             }
00084 
00085             while ( $charPos++ < $splitPos ) {
00086                 ++$bytePos;
00087                 // Move past any tail bytes
00088                 while ( $bytePos < $byteLen && $str[$bytePos] >= "\x80" && $str[$bytePos] < "\xc0" ) {
00089                     ++$bytePos;
00090                 }
00091             }
00092         } else {
00093             $splitPosX = $splitPos + 1;
00094             $charPos = 0; // relative to end of string; we don't care about the actual char position here
00095             $bytePos = $byteLen;
00096             while ( $bytePos > 0 && $charPos-- >= $splitPosX ) {
00097                 --$bytePos;
00098                 // Move past any tail bytes
00099                 while ( $bytePos > 0 && $str[$bytePos] >= "\x80" && $str[$bytePos] < "\xc0" ) {
00100                     --$bytePos;
00101                 }
00102             }
00103         }
00104 
00105         return $bytePos;
00106     }
00107 
00114     public static function mb_strlen( $str, $enc = '' ) {
00115         $counts = count_chars( $str );
00116         $total = 0;
00117 
00118         // Count ASCII bytes
00119         for ( $i = 0; $i < 0x80; $i++ ) {
00120             $total += $counts[$i];
00121         }
00122 
00123         // Count multibyte sequence heads
00124         for ( $i = 0xc0; $i < 0xff; $i++ ) {
00125             $total += $counts[$i];
00126         }
00127         return $total;
00128     }
00129 
00138     public static function mb_strpos( $haystack, $needle, $offset = 0, $encoding = '' ) {
00139         $needle = preg_quote( $needle, '/' );
00140 
00141         $ar = array();
00142         preg_match( '/' . $needle . '/u', $haystack, $ar, PREG_OFFSET_CAPTURE, $offset );
00143 
00144         if ( isset( $ar[0][1] ) ) {
00145             return $ar[0][1];
00146         } else {
00147             return false;
00148         }
00149     }
00150 
00159     public static function mb_strrpos( $haystack, $needle, $offset = 0, $encoding = '' ) {
00160         $needle = preg_quote( $needle, '/' );
00161 
00162         $ar = array();
00163         preg_match_all( '/' . $needle . '/u', $haystack, $ar, PREG_OFFSET_CAPTURE, $offset );
00164 
00165         if ( isset( $ar[0] ) && count( $ar[0] ) > 0 &&
00166             isset( $ar[0][count( $ar[0] ) - 1][1] ) ) {
00167             return $ar[0][count( $ar[0] ) - 1][1];
00168         } else {
00169             return false;
00170         }
00171     }
00172 }