This source file includes following definitions.
- create_transliterator
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_METHOD
- PHP_FUNCTION
- PHP_FUNCTION
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include "php_intl.h"
22 #include "transliterator.h"
23 #include "transliterator_class.h"
24 #include "transliterator_methods.h"
25 #include "intl_data.h"
26 #include "intl_convert.h"
27
28 #include <zend_exceptions.h>
29
30 static int create_transliterator( char *str_id, int str_id_len, long direction, zval *object TSRMLS_DC )
31 {
32 Transliterator_object *to;
33 UChar *ustr_id = NULL;
34 int32_t ustr_id_len = 0;
35 UTransliterator *utrans;
36 UParseError parse_error = {0, -1};
37
38 intl_error_reset( NULL TSRMLS_CC );
39
40 if( ( direction != TRANSLITERATOR_FORWARD ) && (direction != TRANSLITERATOR_REVERSE ) )
41 {
42 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
43 "transliterator_create: invalid direction", 0 TSRMLS_CC );
44 return FAILURE;
45 }
46
47 object_init_ex( object, Transliterator_ce_ptr );
48 TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK;
49
50
51 intl_convert_utf8_to_utf16( &ustr_id, &ustr_id_len, str_id, str_id_len, TRANSLITERATOR_ERROR_CODE_P( to ) );
52 if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) )
53 {
54 intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) TSRMLS_CC );
55 intl_error_set_custom_msg( NULL, "String conversion of id to UTF-16 failed", 0 TSRMLS_CC );
56 zval_dtor( object );
57 return FAILURE;
58 }
59
60
61 utrans = utrans_openU( ustr_id, ustr_id_len, (UTransDirection ) direction,
62 NULL, -1, &parse_error, TRANSLITERATOR_ERROR_CODE_P( to ) );
63 if (ustr_id) {
64 efree( ustr_id );
65 }
66
67 if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) )
68 {
69 char *buf = NULL;
70 intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) TSRMLS_CC );
71 spprintf( &buf, 0, "transliterator_create: unable to open ICU transliterator"
72 " with id \"%s\"", str_id );
73 if( buf == NULL ) {
74 intl_error_set_custom_msg( NULL,
75 "transliterator_create: unable to open ICU transliterator", 0 TSRMLS_CC );
76 }
77 else
78 {
79 intl_error_set_custom_msg( NULL, buf, 1 TSRMLS_CC );
80 efree( buf );
81 }
82 zval_dtor( object );
83 return FAILURE;
84 }
85
86 transliterator_object_construct( object, utrans, TRANSLITERATOR_ERROR_CODE_P( to ) TSRMLS_CC );
87
88 if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) )
89 {
90 intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) TSRMLS_CC );
91 intl_error_set_custom_msg( NULL,
92 "transliterator_create: internal constructor call failed", 0 TSRMLS_CC );
93 zval_dtor( object );
94 return FAILURE;
95 }
96
97 return SUCCESS;
98 }
99
100
101
102
103
104 PHP_FUNCTION( transliterator_create )
105 {
106 char *str_id;
107 int str_id_len;
108 long direction = TRANSLITERATOR_FORWARD;
109 int res;
110
111 TRANSLITERATOR_METHOD_INIT_VARS;
112
113 (void) to;
114
115 if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s|l",
116 &str_id, &str_id_len, &direction ) == FAILURE )
117 {
118 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
119 "transliterator_create: bad arguments", 0 TSRMLS_CC );
120 RETURN_NULL();
121 }
122
123 object = return_value;
124 res = create_transliterator( str_id, str_id_len, direction, object TSRMLS_CC );
125 if( res == FAILURE )
126 RETURN_NULL();
127
128
129 }
130
131
132
133
134
135
136 PHP_FUNCTION( transliterator_create_from_rules )
137 {
138 char *str_rules;
139 int str_rules_len;
140 UChar *ustr_rules = NULL;
141 int32_t ustr_rules_len = 0;
142 long direction = TRANSLITERATOR_FORWARD;
143 UParseError parse_error = {0, -1};
144 UTransliterator *utrans;
145 UChar id[] = {0x52, 0x75, 0x6C, 0x65, 0x73, 0x54, 0x72,
146 0x61, 0x6E, 0x73, 0x50, 0x48, 0x50, 0};
147 TRANSLITERATOR_METHOD_INIT_VARS;
148
149 if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s|l",
150 &str_rules, &str_rules_len, &direction ) == FAILURE )
151 {
152 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
153 "transliterator_create_from_rules: bad arguments", 0 TSRMLS_CC );
154 RETURN_NULL();
155 }
156
157 if( ( direction != TRANSLITERATOR_FORWARD ) && (direction != TRANSLITERATOR_REVERSE ) )
158 {
159 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
160 "transliterator_create_from_rules: invalid direction", 0 TSRMLS_CC );
161 RETURN_NULL();
162 }
163
164 object = return_value;
165 object_init_ex( object, Transliterator_ce_ptr );
166 TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK;
167
168 intl_convert_utf8_to_utf16( &ustr_rules, &ustr_rules_len,
169 str_rules, str_rules_len, TRANSLITERATOR_ERROR_CODE_P( to ) );
170
171
172 INTL_CTOR_CHECK_STATUS( to, "String conversion of rules to UTF-16 failed" );
173
174
175 utrans = utrans_openU( id, ( sizeof( id ) - 1 ) / ( sizeof( *id ) ), (UTransDirection ) direction,
176 ustr_rules, ustr_rules_len, &parse_error, TRANSLITERATOR_ERROR_CODE_P( to ) );
177 if (ustr_rules) {
178 efree( ustr_rules );
179 }
180
181 intl_error_set_code( NULL, INTL_DATA_ERROR_CODE( to ) TSRMLS_CC );
182 if( U_FAILURE( INTL_DATA_ERROR_CODE( to ) ) )
183 {
184 char *msg = NULL;
185 smart_str parse_error_str;
186 parse_error_str = intl_parse_error_to_string( &parse_error );
187 spprintf( &msg, 0, "transliterator_create_from_rules: unable to "
188 "create ICU transliterator from rules (%s)", parse_error_str.c );
189 smart_str_free( &parse_error_str );
190 if( msg != NULL )
191 {
192 intl_errors_set_custom_msg( INTL_DATA_ERROR_P( to ), msg, 1 TSRMLS_CC );
193 efree( msg );
194 }
195 zval_dtor( return_value );
196 RETURN_NULL();
197 }
198 transliterator_object_construct( object, utrans, TRANSLITERATOR_ERROR_CODE_P( to ) TSRMLS_CC );
199
200 INTL_CTOR_CHECK_STATUS( to, "transliterator_create_from_rules: internal constructor call failed" );
201 }
202
203
204
205
206
207
208 PHP_FUNCTION( transliterator_create_inverse )
209 {
210 Transliterator_object *to_orig;
211 UTransliterator *utrans;
212 TRANSLITERATOR_METHOD_INIT_VARS;
213
214 if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
215 &object, Transliterator_ce_ptr ) == FAILURE )
216 {
217 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
218 "transliterator_create_inverse: bad arguments", 0 TSRMLS_CC );
219 RETURN_NULL();
220 }
221
222 TRANSLITERATOR_METHOD_FETCH_OBJECT;
223 to_orig = to;
224
225 object = return_value;
226 object_init_ex( object, Transliterator_ce_ptr );
227 TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK;
228
229 utrans = utrans_openInverse( to_orig->utrans, TRANSLITERATOR_ERROR_CODE_P( to ) );
230 INTL_CTOR_CHECK_STATUS( to, "transliterator_create_inverse: could not create "
231 "inverse ICU transliterator" );
232 transliterator_object_construct( object, utrans, TRANSLITERATOR_ERROR_CODE_P( to ) TSRMLS_CC );
233
234 INTL_CTOR_CHECK_STATUS( to, "transliterator_create: internal constructor call failed" );
235 }
236
237
238
239
240
241
242 PHP_FUNCTION( transliterator_list_ids )
243 {
244 UEnumeration *en;
245 const UChar *elem;
246 int32_t elem_len;
247 UErrorCode status = U_ZERO_ERROR;
248
249 intl_error_reset( NULL TSRMLS_CC );
250
251 if( zend_parse_parameters_none() == FAILURE )
252 {
253
254
255
256 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
257 "transliterator_list_ids: bad arguments", 0 TSRMLS_CC );
258 RETURN_FALSE;
259 }
260
261 en = utrans_openIDs( &status );
262 INTL_CHECK_STATUS( status,
263 "transliterator_list_ids: Failed to obtain registered transliterators" );
264
265 array_init( return_value );
266 while( (elem = uenum_unext( en, &elem_len, &status )) )
267 {
268 char *el_char = NULL;
269 int el_len = 0;
270
271 intl_convert_utf16_to_utf8( &el_char, &el_len, elem, elem_len, &status );
272
273 if( U_FAILURE( status ) )
274 {
275 efree( el_char );
276 break;
277 }
278 else
279 {
280 add_next_index_stringl( return_value, el_char, el_len, 0 );
281 }
282 }
283 uenum_close( en );
284
285 intl_error_set_code( NULL, status TSRMLS_CC );
286 if( U_FAILURE( status ) )
287 {
288 zval_dtor( return_value );
289 RETVAL_FALSE;
290 intl_error_set_custom_msg( NULL, "transliterator_list_ids: "
291 "Failed to build array of registered transliterators", 0 TSRMLS_CC );
292 }
293 }
294
295
296
297
298
299 PHP_FUNCTION( transliterator_transliterate )
300 {
301 char *str;
302 UChar *ustr = NULL,
303 *uresult = NULL;
304 int str_len;
305 int32_t ustr_len = 0,
306 capacity,
307 uresult_len;
308 long start = 0,
309 limit = -1;
310 int success = 0,
311 temp_trans = 0;
312 TRANSLITERATOR_METHOD_INIT_VARS;
313
314 object = getThis();
315
316 if( object == NULL )
317 {
318
319 zval **arg1;
320 if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "Zs|ll",
321 &arg1, &str, &str_len, &start, &limit ) == FAILURE )
322 {
323 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
324 "transliterator_transliterate: bad arguments", 0 TSRMLS_CC );
325 RETURN_FALSE;
326 }
327
328 if( Z_TYPE_PP( arg1 ) == IS_OBJECT &&
329 instanceof_function( Z_OBJCE_PP( arg1 ), Transliterator_ce_ptr TSRMLS_CC ) )
330 {
331 object = *arg1;
332 }
333 else
334 {
335 int res;
336 if(Z_TYPE_PP( arg1 ) != IS_STRING )
337 {
338 SEPARATE_ZVAL( arg1 );
339 convert_to_string( *arg1 );
340 }
341 ALLOC_INIT_ZVAL( object );
342 temp_trans = 1;
343 res = create_transliterator( Z_STRVAL_PP( arg1 ), Z_STRLEN_PP( arg1 ),
344 TRANSLITERATOR_FORWARD, object TSRMLS_CC );
345 if( res == FAILURE )
346 {
347 char *message = intl_error_get_message( NULL TSRMLS_CC );
348 php_error_docref0( NULL TSRMLS_CC, E_WARNING, "Could not create "
349 "transliterator with ID \"%s\" (%s)", Z_STRVAL_PP( arg1 ), message );
350 efree( message );
351
352 goto cleanup;
353 }
354 }
355 }
356 else if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s|ll",
357 &str, &str_len, &start, &limit ) == FAILURE )
358 {
359 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
360 "transliterator_transliterate: bad arguments", 0 TSRMLS_CC );
361 RETURN_FALSE;
362 }
363
364 if( limit < -1 )
365 {
366 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
367 "transliterator_transliterate: \"end\" argument should be "
368 "either non-negative or -1", 0 TSRMLS_CC );
369 RETURN_FALSE;
370 }
371
372 if( start < 0 || ((limit != -1 ) && (start > limit )) )
373 {
374 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
375 "transliterator_transliterate: \"start\" argument should be "
376 "non-negative and not bigger than \"end\" (if defined)", 0 TSRMLS_CC );
377 RETURN_FALSE;
378 }
379
380
381
382 TRANSLITERATOR_METHOD_FETCH_OBJECT;
383
384 intl_convert_utf8_to_utf16( &ustr, &ustr_len, str, str_len,
385 TRANSLITERATOR_ERROR_CODE_P( to ) );
386 INTL_METHOD_CHECK_STATUS( to, "String conversion of string to UTF-16 failed" );
387
388
389
390 if( ( start > ustr_len ) || (( limit != -1 ) && (limit > ustr_len ) ) )
391 {
392 char *msg;
393 spprintf( &msg, 0,
394 "transliterator_transliterate: Neither \"start\" nor the \"end\" "
395 "arguments can exceed the number of UTF-16 code units "
396 "(in this case, %d)", (int) ustr_len );
397 if(msg != NULL )
398 {
399 intl_errors_set( TRANSLITERATOR_ERROR_P( to ), U_ILLEGAL_ARGUMENT_ERROR,
400 msg, 1 TSRMLS_CC );
401 efree( msg );
402 }
403 RETVAL_FALSE;
404 goto cleanup;
405 }
406
407 uresult = safe_emalloc( ustr_len, sizeof( UChar ), 1 * sizeof( UChar ) );
408 capacity = ustr_len + 1;
409
410 while( 1 )
411 {
412 int32_t temp_limit = ( limit == -1 ? ustr_len : (int32_t) limit );
413 memcpy( uresult, ustr, ustr_len * sizeof( UChar ) );
414 uresult_len = ustr_len;
415
416 utrans_transUChars( to->utrans, uresult, &uresult_len, capacity, (int32_t) start,
417 &temp_limit, TRANSLITERATOR_ERROR_CODE_P( to ) );
418 if( TRANSLITERATOR_ERROR_CODE( to ) == U_BUFFER_OVERFLOW_ERROR )
419 {
420 efree( uresult );
421
422 uresult = safe_emalloc( uresult_len, sizeof( UChar ), 1 * sizeof( UChar ) );
423 capacity = uresult_len + 1;
424
425 intl_error_reset( TRANSLITERATOR_ERROR_P( to ) TSRMLS_CC );
426 }
427 else if(TRANSLITERATOR_ERROR_CODE( to ) == U_STRING_NOT_TERMINATED_WARNING )
428 {
429 uresult = safe_erealloc( uresult, uresult_len, sizeof( UChar ), 1 * sizeof( UChar ) );
430
431 intl_error_reset( TRANSLITERATOR_ERROR_P( to ) TSRMLS_CC );
432 break;
433 }
434 else if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) )
435 {
436 intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) TSRMLS_CC );
437 intl_errors_set_custom_msg( TRANSLITERATOR_ERROR_P( to ),
438 "transliterator_transliterate: transliteration failed", 0 TSRMLS_CC );
439 goto cleanup;
440 }
441 else
442 break;
443 }
444
445 uresult[uresult_len] = (UChar) 0;
446
447 success = 1;
448
449 cleanup:
450 if( ustr )
451 efree( ustr );
452
453 if( success ) {
454
455 INTL_METHOD_RETVAL_UTF8( to, uresult, uresult_len, 1 );
456 }
457 else
458 {
459 if( uresult )
460 efree( uresult );
461 RETVAL_FALSE;
462 }
463
464 if (temp_trans )
465 zval_ptr_dtor( &object );
466 }
467
468
469 PHP_METHOD( Transliterator, __construct )
470 {
471
472 zend_throw_exception( NULL,
473 "An object of this type cannot be created with the new operator.",
474 0 TSRMLS_CC );
475 }
476
477
478
479
480
481 PHP_FUNCTION( transliterator_get_error_code )
482 {
483 TRANSLITERATOR_METHOD_INIT_VARS
484
485 if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
486 &object, Transliterator_ce_ptr ) == FAILURE )
487 {
488 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
489 "transliterator_get_error_code: unable to parse input params", 0 TSRMLS_CC );
490
491 RETURN_FALSE;
492 }
493
494
495 to = zend_object_store_get_object( object TSRMLS_CC );
496 if (to == NULL )
497 RETURN_FALSE;
498
499 RETURN_LONG( (long) TRANSLITERATOR_ERROR_CODE( to ) );
500 }
501
502
503
504
505
506
507
508 PHP_FUNCTION( transliterator_get_error_message )
509 {
510 const char* message = NULL;
511 TRANSLITERATOR_METHOD_INIT_VARS
512
513 if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
514 &object, Transliterator_ce_ptr ) == FAILURE )
515 {
516 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
517 "transliterator_get_error_message: unable to parse input params", 0 TSRMLS_CC );
518
519 RETURN_FALSE;
520 }
521
522
523
524 to = zend_object_store_get_object( object TSRMLS_CC );
525 if (to == NULL )
526 RETURN_FALSE;
527
528
529 message = intl_error_get_message( TRANSLITERATOR_ERROR_P( to ) TSRMLS_CC );
530 RETURN_STRING( message, 0 );
531 }
532
533
534
535
536
537
538
539
540
541
542