1 /*
2    +----------------------------------------------------------------------+
3    | This source file is subject to version 3.01 of the PHP license,      |
4    | that is bundled with this package in the file LICENSE, and is        |
5    | available through the world-wide-web at the following url:           |
6    | https://www.php.net/license/3_01.txt                                 |
7    | If you did not receive a copy of the PHP license and are unable to   |
8    | obtain it through the world-wide-web, please send a note to          |
9    | license@php.net so we can mail you a copy immediately.               |
10    +----------------------------------------------------------------------+
11    | Authors: Vadim Savchuk <vsavchuk@productengine.com>                  |
12    |          Dmitry Lakhtyuk <dlakhtyuk@productengine.com>               |
13    +----------------------------------------------------------------------+
14  */
15 
16 #ifdef HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19 
20 #include "php_intl.h"
21 #include "collator_class.h"
22 #include "intl_convert.h"
23 
24 /* {{{ Compare two strings. */
PHP_FUNCTION(collator_compare)25 PHP_FUNCTION( collator_compare )
26 {
27 	char*            str1      = NULL;
28 	char*            str2      = NULL;
29 	size_t              str1_len  = 0;
30 	size_t              str2_len  = 0;
31 
32 	UChar*           ustr1     = NULL;
33 	UChar*           ustr2     = NULL;
34 	int              ustr1_len = 0;
35 	int              ustr2_len = 0;
36 
37 	UCollationResult result;
38 
39 	COLLATOR_METHOD_INIT_VARS
40 
41 	/* Parse parameters. */
42 	if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oss",
43 		&object, Collator_ce_ptr, &str1, &str1_len, &str2, &str2_len ) == FAILURE )
44 	{
45 		RETURN_THROWS();
46 	}
47 
48 	/* Fetch the object. */
49 	COLLATOR_METHOD_FETCH_OBJECT;
50 
51 	if (!co || !co->ucoll) {
52 		intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) );
53 		intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ),
54 			"Object not initialized", 0 );
55 		zend_throw_error(NULL, "Object not initialized");
56 
57 		RETURN_THROWS();
58 	}
59 
60 	/*
61 	 * Compare given strings (converting them to UTF-16 first).
62 	 */
63 
64 	/* First convert the strings to UTF-16. */
65 	intl_convert_utf8_to_utf16(
66 		&ustr1, &ustr1_len, str1, str1_len, COLLATOR_ERROR_CODE_P( co ) );
67 	if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) )
68 	{
69 		/* Set global error code. */
70 		intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) );
71 
72 		/* Set error messages. */
73 		intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ),
74 			"Error converting first argument to UTF-16", 0 );
75 		if (ustr1) {
76 			efree( ustr1 );
77 		}
78 		RETURN_FALSE;
79 	}
80 
81 	intl_convert_utf8_to_utf16(
82 		&ustr2, &ustr2_len, str2, str2_len, COLLATOR_ERROR_CODE_P( co ) );
83 	if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) )
84 	{
85 		/* Set global error code. */
86 		intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) );
87 
88 		/* Set error messages. */
89 		intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ),
90 			"Error converting second argument to UTF-16", 0 );
91 		if (ustr1) {
92 			efree( ustr1 );
93 		}
94 		if (ustr2) {
95 			efree( ustr2 );
96 		}
97 		RETURN_FALSE;
98 	}
99 
100 	/* Then compare them. */
101 	result = ucol_strcoll(
102 		co->ucoll,
103 		ustr1, ustr1_len,
104 		ustr2, ustr2_len );
105 
106 	if( ustr1 )
107 		efree( ustr1 );
108 	if( ustr2 )
109 		efree( ustr2 );
110 
111 	/* Return result of the comparison. */
112 	RETURN_LONG( result );
113 }
114 /* }}} */
115