This source file includes following definitions.
- collator_convert_hash_item_from_utf8_to_utf16
- collator_convert_hash_item_from_utf16_to_utf8
- collator_convert_hash_from_utf8_to_utf16
- collator_convert_hash_from_utf16_to_utf8
- collator_convert_zstr_utf16_to_utf8
- collator_convert_zstr_utf8_to_utf16
- collator_convert_object_to_string
- collator_convert_string_to_number
- collator_convert_string_to_double
- collator_convert_string_to_number_if_possible
- collator_make_printable_zval
- collator_normalize_sort_argument
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21
22 #include "php_intl.h"
23 #include "collator_class.h"
24 #include "collator_is_numeric.h"
25 #include "collator_convert.h"
26 #include "intl_convert.h"
27
28 #include <unicode/ustring.h>
29 #include <php.h>
30
31 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION <= 1)
32 #define CAST_OBJECT_SHOULD_FREE ,0
33 #else
34 #define CAST_OBJECT_SHOULD_FREE
35 #endif
36
37 #define COLLATOR_CONVERT_RETURN_FAILED(retval) { \
38 zval_add_ref( &retval ); \
39 return retval; \
40 }
41
42
43 static void collator_convert_hash_item_from_utf8_to_utf16(
44 HashTable* hash, int hashKeyType, char* hashKey, ulong hashIndex,
45 UErrorCode* status )
46 {
47 const char* old_val;
48 int old_val_len;
49 UChar* new_val = NULL;
50 int new_val_len = 0;
51 zval** hashData = NULL;
52 zval* znew_val = NULL;
53
54
55 zend_hash_get_current_data( hash, (void**) &hashData );
56
57
58 if( Z_TYPE_P( *hashData ) != IS_STRING )
59 return;
60
61 old_val = Z_STRVAL_P( *hashData );
62 old_val_len = Z_STRLEN_P( *hashData );
63
64
65 intl_convert_utf8_to_utf16( &new_val, &new_val_len, old_val, old_val_len, status );
66 if( U_FAILURE( *status ) )
67 return;
68
69
70 MAKE_STD_ZVAL( znew_val );
71 ZVAL_STRINGL( znew_val, (char*)new_val, UBYTES(new_val_len), FALSE );
72
73 if( hashKeyType == HASH_KEY_IS_STRING )
74 {
75 zend_hash_update( hash, hashKey, strlen( hashKey ) + 1,
76 (void*) &znew_val, sizeof(zval*), NULL );
77 }
78 else
79 {
80 zend_hash_index_update( hash, hashIndex,
81 (void*) &znew_val, sizeof(zval*), NULL );
82 }
83 }
84
85
86
87 static void collator_convert_hash_item_from_utf16_to_utf8(
88 HashTable* hash, int hashKeyType, char* hashKey, ulong hashIndex,
89 UErrorCode* status )
90 {
91 const char* old_val;
92 int old_val_len;
93 char* new_val = NULL;
94 int new_val_len = 0;
95 zval** hashData = NULL;
96 zval* znew_val = NULL;
97
98
99 zend_hash_get_current_data( hash, (void**) &hashData );
100
101
102 if( Z_TYPE_P( *hashData ) != IS_STRING )
103 return;
104
105 old_val = Z_STRVAL_P( *hashData );
106 old_val_len = Z_STRLEN_P( *hashData );
107
108
109 intl_convert_utf16_to_utf8( &new_val, &new_val_len,
110 (UChar*)old_val, UCHARS(old_val_len), status );
111 if( U_FAILURE( *status ) )
112 return;
113
114
115 MAKE_STD_ZVAL( znew_val );
116 ZVAL_STRINGL( znew_val, (char*)new_val, new_val_len, FALSE );
117
118 if( hashKeyType == HASH_KEY_IS_STRING )
119 {
120 zend_hash_update( hash, hashKey, strlen( hashKey ) + 1,
121 (void*) &znew_val, sizeof(zval*), NULL );
122 }
123 else
124 {
125 zend_hash_index_update( hash, hashIndex,
126 (void*) &znew_val, sizeof(zval*), NULL );
127 }
128 }
129
130
131
132
133
134 void collator_convert_hash_from_utf8_to_utf16( HashTable* hash, UErrorCode* status )
135 {
136 ulong hashIndex = 0;
137 char* hashKey = NULL;
138 int hashKeyType = 0;
139
140 zend_hash_internal_pointer_reset( hash );
141 while( ( hashKeyType = zend_hash_get_current_key( hash, &hashKey, &hashIndex, 0 ) )
142 != HASH_KEY_NON_EXISTENT )
143 {
144
145 collator_convert_hash_item_from_utf8_to_utf16(
146 hash, hashKeyType, hashKey, hashIndex, status );
147 if( U_FAILURE( *status ) )
148 return;
149
150
151 zend_hash_move_forward( hash );
152 }
153 }
154
155
156
157
158
159 void collator_convert_hash_from_utf16_to_utf8( HashTable* hash, UErrorCode* status )
160 {
161 ulong hashIndex = 0;
162 char* hashKey = NULL;
163 int hashKeyType = 0;
164
165 zend_hash_internal_pointer_reset( hash );
166 while( ( hashKeyType = zend_hash_get_current_key( hash, &hashKey, &hashIndex, 0 ) )
167 != HASH_KEY_NON_EXISTENT )
168 {
169
170 collator_convert_hash_item_from_utf16_to_utf8(
171 hash, hashKeyType, hashKey, hashIndex, status );
172 if( U_FAILURE( *status ) ) {
173 return;
174 }
175
176
177 zend_hash_move_forward( hash );
178 }
179 }
180
181
182
183
184
185
186
187
188
189
190 zval* collator_convert_zstr_utf16_to_utf8( zval* utf16_zval )
191 {
192 zval* utf8_zval = NULL;
193 char* str = NULL;
194 int str_len = 0;
195 UErrorCode status = U_ZERO_ERROR;
196
197
198 intl_convert_utf16_to_utf8( &str, &str_len,
199 (UChar*) Z_STRVAL_P(utf16_zval), UCHARS( Z_STRLEN_P(utf16_zval) ), &status );
200 if( U_FAILURE( status ) )
201 php_error( E_WARNING, "Error converting utf16 to utf8 in collator_convert_zval_utf16_to_utf8()" );
202
203 ALLOC_INIT_ZVAL( utf8_zval );
204 ZVAL_STRINGL( utf8_zval, str, str_len, FALSE );
205
206 return utf8_zval;
207 }
208
209
210
211
212
213
214
215
216
217
218 zval* collator_convert_zstr_utf8_to_utf16( zval* utf8_zval )
219 {
220 zval* zstr = NULL;
221 UChar* ustr = NULL;
222 int ustr_len = 0;
223 UErrorCode status = U_ZERO_ERROR;
224
225
226 intl_convert_utf8_to_utf16(
227 &ustr, &ustr_len,
228 Z_STRVAL_P( utf8_zval ), Z_STRLEN_P( utf8_zval ),
229 &status );
230 if( U_FAILURE( status ) )
231 php_error( E_WARNING, "Error casting object to string in collator_convert_zstr_utf8_to_utf16()" );
232
233
234 ALLOC_INIT_ZVAL( zstr );
235 ZVAL_STRINGL( zstr, (char*)ustr, UBYTES(ustr_len), FALSE );
236
237 return zstr;
238 }
239
240
241
242
243
244 zval* collator_convert_object_to_string( zval* obj TSRMLS_DC )
245 {
246 zval* zstr = NULL;
247 UErrorCode status = U_ZERO_ERROR;
248 UChar* ustr = NULL;
249 int ustr_len = 0;
250
251
252 if( Z_TYPE_P( obj ) != IS_OBJECT )
253 {
254 COLLATOR_CONVERT_RETURN_FAILED( obj );
255 }
256
257
258 if( Z_OBJ_HT_P(obj)->get )
259 {
260 zstr = Z_OBJ_HT_P(obj)->get( obj TSRMLS_CC );
261
262 switch( Z_TYPE_P( zstr ) )
263 {
264 case IS_OBJECT:
265 {
266
267 zval_ptr_dtor( &zstr );
268 COLLATOR_CONVERT_RETURN_FAILED( obj );
269 } break;
270
271 case IS_STRING:
272 break;
273
274 default:
275 {
276 convert_to_string( zstr );
277 } break;
278 }
279 }
280 else if( Z_OBJ_HT_P(obj)->cast_object )
281 {
282 ALLOC_INIT_ZVAL( zstr );
283
284 if( Z_OBJ_HT_P(obj)->cast_object( obj, zstr, IS_STRING CAST_OBJECT_SHOULD_FREE TSRMLS_CC ) == FAILURE )
285 {
286
287 zval_ptr_dtor( &zstr );
288 COLLATOR_CONVERT_RETURN_FAILED( obj );
289 }
290 }
291
292
293 if( zstr == NULL )
294 {
295 COLLATOR_CONVERT_RETURN_FAILED( obj );
296 }
297
298
299 intl_convert_utf8_to_utf16(
300 &ustr, &ustr_len,
301 Z_STRVAL_P( zstr ), Z_STRLEN_P( zstr ),
302 &status );
303 if( U_FAILURE( status ) )
304 php_error( E_WARNING, "Error casting object to string in collator_convert_object_to_string()" );
305
306
307 zval_dtor( zstr );
308
309
310 ZVAL_STRINGL( zstr, (char*)ustr, UBYTES(ustr_len), FALSE );
311
312
313
314
315
316 return zstr;
317 }
318
319
320
321
322
323
324
325
326
327
328 zval* collator_convert_string_to_number( zval* str )
329 {
330 zval* num = collator_convert_string_to_number_if_possible( str );
331 if( num == str )
332 {
333
334 zval_ptr_dtor( &num );
335
336 ALLOC_INIT_ZVAL( num );
337 ZVAL_LONG( num, 0 );
338 }
339
340 return num;
341 }
342
343
344
345
346
347
348
349
350
351
352 zval* collator_convert_string_to_double( zval* str )
353 {
354 zval* num = collator_convert_string_to_number( str );
355 if( Z_TYPE_P(num) == IS_LONG )
356 {
357 ZVAL_DOUBLE( num, Z_LVAL_P( num ) );
358 }
359
360 return num;
361 }
362
363
364
365
366
367
368
369
370
371
372
373 zval* collator_convert_string_to_number_if_possible( zval* str )
374 {
375 zval* num = NULL;
376 int is_numeric = 0;
377 long lval = 0;
378 double dval = 0;
379
380 if( Z_TYPE_P( str ) != IS_STRING )
381 {
382 COLLATOR_CONVERT_RETURN_FAILED( str );
383 }
384
385 if( ( is_numeric = collator_is_numeric( (UChar*) Z_STRVAL_P(str), UCHARS( Z_STRLEN_P(str) ), &lval, &dval, 1 ) ) )
386 {
387 ALLOC_INIT_ZVAL( num );
388
389 if( is_numeric == IS_LONG )
390 Z_LVAL_P(num) = lval;
391 if( is_numeric == IS_DOUBLE )
392 Z_DVAL_P(num) = dval;
393
394 Z_TYPE_P(num) = is_numeric;
395 }
396 else
397 {
398 COLLATOR_CONVERT_RETURN_FAILED( str );
399 }
400
401 return num;
402 }
403
404
405
406
407
408
409
410
411
412
413 zval* collator_make_printable_zval( zval* arg )
414 {
415 zval arg_copy;
416 int use_copy = 0;
417 zval* str = NULL;
418
419 if( Z_TYPE_P(arg) != IS_STRING )
420 {
421 zend_make_printable_zval(arg, &arg_copy, &use_copy);
422
423 if( use_copy )
424 {
425 str = collator_convert_zstr_utf8_to_utf16( &arg_copy );
426 zval_dtor( &arg_copy );
427 }
428 else
429 {
430 str = collator_convert_zstr_utf8_to_utf16( arg );
431 }
432 }
433 else
434 {
435 COLLATOR_CONVERT_RETURN_FAILED( arg );
436 }
437
438 return str;
439 }
440
441
442
443
444
445
446
447
448
449
450
451 zval* collator_normalize_sort_argument( zval* arg )
452 {
453 zval* n_arg = NULL;
454
455 if( Z_TYPE_P( arg ) != IS_STRING )
456 {
457
458
459
460 COLLATOR_CONVERT_RETURN_FAILED( arg );
461 }
462
463
464 n_arg = collator_convert_string_to_number_if_possible( arg );
465
466 if( n_arg == arg )
467 {
468
469 zval_ptr_dtor( &n_arg );
470
471
472 n_arg = collator_convert_zstr_utf16_to_utf8( arg );
473 }
474
475 return n_arg;
476 }
477
478
479
480
481
482
483
484
485