andrei          Wed Oct  4 17:25:12 2006 UTC

  Modified files:              
    /php-src/ext/standard       string.c 
  Log:
  Unicode support in substr_compare().
  
  
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/string.c?r1=1.602&r2=1.603&diff_format=u
Index: php-src/ext/standard/string.c
diff -u php-src/ext/standard/string.c:1.602 php-src/ext/standard/string.c:1.603
--- php-src/ext/standard/string.c:1.602 Wed Oct  4 11:12:21 2006
+++ php-src/ext/standard/string.c       Wed Oct  4 17:25:12 2006
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: string.c,v 1.602 2006/10/04 11:12:21 tony2001 Exp $ */
+/* $Id: string.c,v 1.603 2006/10/04 17:25:12 andrei Exp $ */
 
 /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */
 
@@ -7316,17 +7316,19 @@
 }
 /* }}} */
 
-/* {{{ proto int substr_compare(string main_str, string str, int offset [, int 
length [, bool case_sensitivity]])
+/* {{{ proto int substr_compare(string main_str, string str, int offset [, int 
length [, bool case_sensitivity]]) U
    Binary safe optionally case insensitive comparison of 2 strings from an 
offset, up to length characters */
 PHP_FUNCTION(substr_compare)
 {
-       char *s1, *s2;
+       zstr s1, s2;
        int s1_len, s2_len;
-       long offset, len=0;
+       zend_uchar str_type;
+       long offset, start_offset, end_offset, len=0;
        zend_bool cs=0;
        uint cmp_len;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl|lb", &s1, 
&s1_len, &s2, &s2_len, &offset, &len, &cs) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "TTl|lb", &s1, 
&s1_len,
+                                                         &str_type, &s2, 
&s2_len, &str_type, &offset, &len, &cs) == FAILURE) {
                RETURN_FALSE;
        }
 
@@ -7335,22 +7337,61 @@
                RETURN_FALSE;
        }
 
-       if (offset < 0) {
-               offset = s1_len + offset;
-               offset = (offset < 0) ? 0 : offset;
-       }
+       if (str_type == IS_UNICODE) {
+               /* calculate starting offset of the segment */
+               if (offset < 0) {
+                       if (-offset > s1_len) {
+                               start_offset = 0;
+                       } else {
+                               start_offset = s1_len;
+                               U16_BACK_N(s1.u, 0, start_offset, -offset);
+                       }
+               } else {
+                       start_offset = 0;
+                       U16_FWD_N(s1.u, start_offset, s1_len, offset);
+               }
 
-       if ((offset + len) > s1_len) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "The start position 
cannot exceed initial string length");
-               RETURN_FALSE;
-       }
+               /* calculate ending offset of the segment */
+               if (len) {
+                       end_offset = start_offset;
+                       while (len > 0 && end_offset < s1_len) {
+                               U16_FWD_1_UNSAFE(s1.u, end_offset);
+                               --len;
+                       }
+
+                       if (len > 0) {
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"The specified segment exceeds string length");
+                               RETURN_FALSE;
+                       }
+               } else {
+                       end_offset = s1_len;
+               }
 
-       cmp_len = (uint) (len ? len : MAX(s2_len, (s1_len - offset)));
+               cmp_len = MAX(s2_len, (end_offset - start_offset));
 
-       if (!cs) {
-               RETURN_LONG(zend_binary_strncmp(s1 + offset, (s1_len - offset), 
s2, s2_len, cmp_len));
+               if (!cs) {
+                       RETURN_LONG(zend_u_binary_strncmp(s1.u + start_offset, 
(s1_len - start_offset), s2.u, s2_len, cmp_len));
+               } else {
+                       RETURN_LONG(zend_u_binary_strncasecmp(s1.u + 
start_offset, (s1_len - start_offset), s2.u, s2_len, cmp_len));
+               }
        } else {
-               RETURN_LONG(zend_binary_strncasecmp(s1 + offset, (s1_len - 
offset), s2, s2_len, cmp_len));
+               if (offset < 0) {
+                       offset = s1_len + offset;
+                       offset = (offset < 0) ? 0 : offset;
+               }
+
+               if ((offset + len) > s1_len) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "The 
specified segment exceeds string length");
+                       RETURN_FALSE;
+               }
+
+               cmp_len = (uint) (len ? len : MAX(s2_len, (s1_len - offset)));
+
+               if (!cs) {
+                       RETURN_LONG(zend_binary_strncmp(s1.s + offset, (s1_len 
- offset), s2.s, s2_len, cmp_len));
+               } else {
+                       RETURN_LONG(zend_binary_strncasecmp(s1.s + offset, 
(s1_len - offset), s2.s, s2_len, cmp_len));
+               }
        }
 }
 /* }}} */

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to