@@ -1713,41 +1713,10 @@ PHP_FUNCTION(mb_output_handler)
1713
1713
/* {{{ Convert a multibyte string to an array. If split_length is specified,
1714
1714
break the string down into chunks each split_length characters long. */
1715
1715
1716
- /* structure to pass split params to the callback */
1717
- struct mbfl_split_params {
1718
- zval * return_value ; /* php function return value structure pointer */
1719
- mbfl_string * result_string ; /* string to store result chunk */
1720
- size_t mb_chunk_length ; /* actual chunk length in chars */
1721
- size_t split_length ; /* split length in chars */
1722
- mbfl_convert_filter * next_filter ; /* widechar to encoding converter */
1723
- };
1724
-
1725
- /* callback function to fill split array */
1726
- static int mbfl_split_output (int c , void * data )
1727
- {
1728
- struct mbfl_split_params * params = (struct mbfl_split_params * )data ; /* cast passed data */
1729
-
1730
- (* params -> next_filter -> filter_function )(c , params -> next_filter ); /* decoder filter */
1731
-
1732
- if (params -> split_length == ++ params -> mb_chunk_length ) { /* if current chunk size reached defined chunk size or last char reached */
1733
- mbfl_convert_filter_flush (params -> next_filter );/* concatenate separate decoded chars to the solid string */
1734
- mbfl_memory_device * device = (mbfl_memory_device * )params -> next_filter -> data ; /* chars container */
1735
- mbfl_string * chunk = params -> result_string ;
1736
- mbfl_memory_device_result (device , chunk ); /* make chunk */
1737
- add_next_index_stringl (params -> return_value , (const char * )chunk -> val , chunk -> len ); /* add chunk to the array */
1738
- efree (chunk -> val );
1739
- params -> mb_chunk_length = 0 ; /* reset mb_chunk size */
1740
- }
1741
-
1742
- return 0 ;
1743
- }
1744
-
1745
1716
/* TODO Document this function on php.net */
1746
1717
PHP_FUNCTION (mb_str_split )
1747
1718
{
1748
1719
zend_string * str , * encoding = NULL ;
1749
- size_t mb_len , chunks , chunk_len ;
1750
- mbfl_string string , result_string ;
1751
1720
zend_long split_length = 1 ;
1752
1721
1753
1722
ZEND_PARSE_PARAMETERS_START (1 , 3 )
@@ -1762,91 +1731,17 @@ PHP_FUNCTION(mb_str_split)
1762
1731
RETURN_THROWS ();
1763
1732
}
1764
1733
1765
- string .val = (unsigned char * ) ZSTR_VAL (str );
1766
- string .len = ZSTR_LEN (str );
1767
- const mbfl_encoding * mbfl_encoding = string .encoding = php_mb_get_encoding (encoding , 3 );
1768
- if (!string .encoding ) {
1734
+ const mbfl_encoding * mbfl_encoding = php_mb_get_encoding (encoding , 3 );
1735
+ if (!mbfl_encoding ) {
1769
1736
RETURN_THROWS ();
1770
1737
}
1771
1738
1772
- const char * p = ZSTR_VAL (str );
1773
- const char * last = ZSTR_VAL (str ) + ZSTR_LEN (str );
1774
-
1775
- /* first scenario: 1/2/4-byte fixed width encoding */
1776
- if (mbfl_encoding -> flag & MBFL_ENCTYPE_SBCS ) { /* 1 byte */
1777
- mb_len = string .len ;
1778
- chunk_len = (size_t )split_length ; /* chunk length in bytes */
1779
- } else if (mbfl_encoding -> flag & (MBFL_ENCTYPE_WCS2BE | MBFL_ENCTYPE_WCS2LE )) { /* 2 bytes */
1780
- mb_len = string .len / 2 ;
1781
- chunk_len = split_length * 2 ;
1782
- } else if (mbfl_encoding -> flag & (MBFL_ENCTYPE_WCS4BE | MBFL_ENCTYPE_WCS4LE )) { /* 4 bytes */
1783
- mb_len = string .len / 4 ;
1784
- chunk_len = split_length * 4 ;
1785
- } else if (mbfl_encoding -> mblen_table ) {
1786
- /* second scenario: variable width encoding with length table */
1787
- const unsigned char * mbtab = mbfl_encoding -> mblen_table ;
1788
-
1789
- /* assume that we have 1-byte characters */
1790
- array_init_size (return_value , (string .len + split_length ) / split_length ); /* round up */
1791
-
1792
- while (p < last ) {
1793
- char * chunk_p = p ; /* pointer to first byte in chunk */
1794
-
1795
- for (int char_count = 0 ; char_count < split_length && p < last ; char_count ++ ) {
1796
- p += mbtab [* (unsigned char * )p ]; /* character byte length table */
1797
- }
1798
- if (p > last ) { /* check if chunk is in bounds */
1799
- p = last ;
1800
- }
1801
- add_next_index_stringl (return_value , chunk_p , p - chunk_p );
1802
- }
1803
- return ;
1804
- } else {
1805
- /* third scenario: other multibyte encodings */
1806
- /* assume that we have 1-byte characters */
1807
- array_init_size (return_value , (string .len + split_length ) / split_length ); /* round up */
1808
-
1809
- /* decoder filter to decode wchar to encoding */
1810
- mbfl_memory_device device ;
1811
- mbfl_memory_device_init (& device , split_length + 1 , 0 );
1812
-
1813
- mbfl_convert_filter * decoder = mbfl_convert_filter_new (& mbfl_encoding_wchar , string .encoding ,
1814
- mbfl_memory_device_output , NULL , & device );
1815
- ZEND_ASSERT (decoder );
1816
-
1817
- /* wchar filter */
1818
- mbfl_string_init (& result_string ); /* mbfl_string to store chunk in the callback */
1819
- struct mbfl_split_params params = { /* init callback function params structure */
1820
- .return_value = return_value ,
1821
- .result_string = & result_string ,
1822
- .mb_chunk_length = 0 ,
1823
- .split_length = (size_t )split_length ,
1824
- .next_filter = decoder ,
1825
- };
1826
-
1827
- mbfl_convert_filter * filter = mbfl_convert_filter_new (string .encoding , & mbfl_encoding_wchar ,
1828
- mbfl_split_output , NULL , & params );
1829
- ZEND_ASSERT (filter );
1830
-
1831
- while (p < last - 1 ) { /* cycle each byte except last with callback function */
1832
- (* filter -> filter_function )(* p ++ , filter );
1833
- }
1834
- params .mb_chunk_length = split_length - 1 ; /* force to finish current chunk */
1835
- (* filter -> filter_function )(* p ++ , filter ); /* process last char */
1836
-
1837
- mbfl_convert_filter_delete (decoder );
1838
- mbfl_convert_filter_delete (filter );
1839
- mbfl_memory_device_clear (& device );
1840
- return ;
1841
- }
1739
+ mbfl_string string ;
1740
+ string .val = (unsigned char * )ZSTR_VAL (str );
1741
+ string .len = ZSTR_LEN (str );
1742
+ string .encoding = mbfl_encoding ;
1842
1743
1843
- /* first scenario: 1/2/4-byte fixed width encoding */
1844
- chunks = (mb_len + split_length - 1 ) / split_length ; /* round up */
1845
- array_init_size (return_value , chunks );
1846
- while (chunks -- ) {
1847
- add_next_index_stringl (return_value , p , chunk_len );
1848
- p += chunk_len ;
1849
- }
1744
+ RETVAL_ARR (mbfl_str_split (& string , split_length ));
1850
1745
}
1851
1746
/* }}} */
1852
1747
0 commit comments