Annotation of embedaddon/php/ext/intl/transliterator/transliterator_class.c, revision 1.1.1.2
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
5: | This source file is subject to version 3.01 of the PHP license, |
6: | that is bundled with this package in the file LICENSE, and is |
7: | available through the world-wide-web at the following url: |
8: | http://www.php.net/license/3_01.txt |
9: | If you did not receive a copy of the PHP license and are unable to |
10: | obtain it through the world-wide-web, please send a note to |
11: | license@php.net so we can mail you a copy immediately. |
12: +----------------------------------------------------------------------+
13: | Authors: Gustavo Lopes <cataphract@php.net> |
14: +----------------------------------------------------------------------+
15: */
16:
17: #include "transliterator_class.h"
18: #include "php_intl.h"
19: #include "transliterator_methods.h"
20: #include "intl_error.h"
21: #include "intl_convert.h"
22: #include "intl_data.h"
23:
24: #include <unicode/utrans.h>
25:
26: zend_class_entry *Transliterator_ce_ptr = NULL;
27:
28: zend_object_handlers Transliterator_handlers;
29:
30: /* {{{ int transliterator_object_construct( zval *object, UTransliterator *utrans, UErrorCode *status TSRMLS_DC )
31: * Initialize internals of Transliterator_object.
32: */
33: int transliterator_object_construct( zval *object,
34: UTransliterator *utrans,
35: UErrorCode *status TSRMLS_DC )
36: {
37: const UChar *ustr_id;
38: int32_t ustr_id_len;
39: char *str_id;
40: int str_id_len;
41: Transliterator_object *to;
42:
43: TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK;
44:
45: assert( to->utrans == NULL );
46: /* this assignment must happen before any return with failure because the
47: * caller relies on it always being made (so it can just destroy the object
48: * to close the transliterator) */
49: to->utrans = utrans;
50:
51: ustr_id = utrans_getUnicodeID( utrans, &ustr_id_len );
52: intl_convert_utf16_to_utf8( &str_id, &str_id_len, ustr_id, (int ) ustr_id_len, status );
53: if( U_FAILURE( *status ) )
54: {
55: return FAILURE;
56: }
57:
58: zend_update_property_stringl( Transliterator_ce_ptr, object,
59: "id", sizeof( "id" ) - 1, str_id, str_id_len TSRMLS_CC );
60: efree( str_id );
61: return SUCCESS;
62: }
63: /* }}} */
64:
65: /*
66: * Auxiliary functions needed by objects of 'Transliterator' class
67: */
68:
69: /* {{{ void transliterator_object_init( Transliterator_object* to )
70: * Initialize internals of Transliterator_object.
71: */
72: static void transliterator_object_init( Transliterator_object* to TSRMLS_DC )
73: {
74: if( !to )
75: return;
76:
77: intl_error_init( TRANSLITERATOR_ERROR_P( to ) TSRMLS_CC );
78: }
79: /* }}} */
80:
81: /* {{{ void transliterator_object_destroy( Transliterator_object* to )
82: * Clean up mem allocted by internals of Transliterator_object
83: */
84: static void transliterator_object_destroy( Transliterator_object* to TSRMLS_DC )
85: {
86: if( !to )
87: return;
88:
89: if( to->utrans )
90: {
91: utrans_close( to->utrans );
92: to->utrans = NULL;
93: }
94:
95: intl_error_reset( TRANSLITERATOR_ERROR_P( to ) TSRMLS_CC );
96: }
97: /* }}} */
98:
99: /* {{{ Transliterator_objects_dtor */
100: static void Transliterator_objects_dtor(
101: void *object,
102: zend_object_handle handle TSRMLS_DC )
103: {
104: zend_objects_destroy_object( object, handle TSRMLS_CC );
105: }
106: /* }}} */
107:
108: /* {{{ Transliterator_objects_free */
109: static void Transliterator_objects_free( zend_object *object TSRMLS_DC )
110: {
111: Transliterator_object* to = (Transliterator_object*) object;
112:
113: zend_object_std_dtor( &to->zo TSRMLS_CC );
114:
115: transliterator_object_destroy( to TSRMLS_CC );
116:
117: efree( to );
118: }
119: /* }}} */
120:
121: /* {{{ Transliterator_object_create */
122: static zend_object_value Transliterator_object_create(
123: zend_class_entry *ce TSRMLS_DC )
124: {
125: zend_object_value retval;
126: Transliterator_object* intern;
127:
128: intern = ecalloc( 1, sizeof( Transliterator_object ) );
129:
130: zend_object_std_init( &intern->zo, ce TSRMLS_CC );
131: #if PHP_VERSION_ID < 50399
132: zend_hash_copy( intern->zo.properties, &(ce->default_properties ),
133: (copy_ctor_func_t) zval_add_ref, NULL, sizeof( zval* ) );
134: #else
135: object_properties_init( (zend_object*) intern, ce );
136: #endif
137: transliterator_object_init( intern TSRMLS_CC );
138:
139: retval.handle = zend_objects_store_put(
140: intern,
141: Transliterator_objects_dtor,
142: (zend_objects_free_object_storage_t) Transliterator_objects_free,
143: NULL TSRMLS_CC );
144:
145: retval.handlers = &Transliterator_handlers;
146:
147: return retval;
148: }
149: /* }}} */
150:
151: /*
152: * Object handlers for Transliterator class (and subclasses)
153: */
154:
155: /* {{{ clone handler for Transliterator */
156: static zend_object_value Transliterator_clone_obj( zval *object TSRMLS_DC )
157: {
158: Transliterator_object *to_orig,
159: *to_new;
160: zend_object_value ret_val;
161: intl_error_reset( NULL TSRMLS_CC );
162:
163: to_orig = zend_object_store_get_object( object TSRMLS_CC );
164: intl_error_reset( INTL_DATA_ERROR_P( to_orig ) TSRMLS_CC );
1.1.1.2 ! misho 165: ret_val = Transliterator_ce_ptr->create_object( Z_OBJCE_P( object ) TSRMLS_CC );
1.1 misho 166: to_new = zend_object_store_get_object_by_handle( ret_val.handle TSRMLS_CC );
167:
168: zend_objects_clone_members( &to_new->zo, ret_val,
169: &to_orig->zo, Z_OBJ_HANDLE_P( object ) TSRMLS_CC );
170:
171: if( to_orig->utrans != NULL )
172: {
173: UTransliterator *utrans = NULL;
174: zval tempz; /* dummy zval to pass to transliterator_object_construct */
175:
176: /* guaranteed to return NULL if it fails */
177: utrans = utrans_clone( to_orig->utrans, TRANSLITERATOR_ERROR_CODE_P( to_orig ) );
178:
179: if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to_orig ) ) )
180: goto err;
181:
182: Z_OBJVAL( tempz ) = ret_val;
183: transliterator_object_construct( &tempz, utrans,
184: TRANSLITERATOR_ERROR_CODE_P( to_orig ) TSRMLS_CC );
185:
186: if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to_orig ) ) )
187: {
188: char *err_msg;
189: err:
190:
191: if( utrans != NULL )
192: transliterator_object_destroy( to_new TSRMLS_CC );
193:
194: /* set the error anyway, in case in the future we decide not to
195: * throw an error. It also helps build the error message */
196: intl_error_set_code( NULL, INTL_DATA_ERROR_CODE( to_orig ) TSRMLS_CC );
197: intl_errors_set_custom_msg( TRANSLITERATOR_ERROR_P( to_orig ),
198: "Could not clone transliterator", 0 TSRMLS_CC );
199:
200: err_msg = intl_error_get_message( TRANSLITERATOR_ERROR_P( to_orig ) TSRMLS_CC );
201: php_error_docref( NULL TSRMLS_CC, E_ERROR, "%s", err_msg );
202: efree( err_msg ); /* if it's changed into a warning */
203: /* do not destroy tempz; we need to return something */
204: }
205: }
206: else
207: {
208: /* We shouldn't have unconstructed objects in the first place */
209: php_error_docref( NULL TSRMLS_CC, E_WARNING,
210: "Cloning unconstructed transliterator." );
211: }
212:
213: return ret_val;
214: }
215: /* }}} */
216:
217: #if PHP_VERSION_ID >= 50399
218: # define TRANSLITERATOR_PROPERTY_HANDLER_PROLOG \
219: zval tmp_member; \
220: if( Z_TYPE_P( member ) != IS_STRING ) \
221: { \
222: tmp_member = *member; \
223: zval_copy_ctor( &tmp_member ); \
224: convert_to_string( &tmp_member ); \
225: member = &tmp_member; \
226: key = NULL; \
227: }
228: #else
229: # define TRANSLITERATOR_PROPERTY_HANDLER_PROLOG \
230: zval tmp_member; \
231: if( Z_TYPE_P( member ) != IS_STRING ) \
232: { \
233: tmp_member = *member; \
234: zval_copy_ctor( &tmp_member ); \
235: convert_to_string( &tmp_member ); \
236: member = &tmp_member; \
237: }
238: #endif
239:
240: #define TRANSLITERATOR_PROPERTY_HANDLER_EPILOG \
241: if( member == &tmp_member ) \
242: { \
243: zval_dtor( &tmp_member ); \
244: }
245:
246: /* {{{ get_property_ptr_ptr handler */
247: #if PHP_VERSION_ID < 50399
248: static zval **Transliterator_get_property_ptr_ptr( zval *object, zval *member TSRMLS_DC )
249: #else
250: static zval **Transliterator_get_property_ptr_ptr( zval *object, zval *member,
251: const struct _zend_literal *key TSRMLS_DC )
252: #endif
253: {
254: zval **retval;
255:
256: TRANSLITERATOR_PROPERTY_HANDLER_PROLOG;
257:
258: if(zend_binary_strcmp( "id", sizeof( "id" ) - 1,
259: Z_STRVAL_P( member ), Z_STRLEN_P( member ) ) == 0 )
260: {
261: retval = NULL; /* fallback to read_property */
262: }
263: else
264: {
265: #if PHP_VERSION_ID < 50399
266: retval = std_object_handlers.get_property_ptr_ptr( object, member TSRMLS_CC );
267: #else
268: retval = std_object_handlers.get_property_ptr_ptr( object, member, key TSRMLS_CC );
269: #endif
270: }
271:
272: TRANSLITERATOR_PROPERTY_HANDLER_EPILOG;
273:
274: return retval;
275: }
276: /* }}} */
277:
278: /* {{{ read_property handler */
279: #if PHP_VERSION_ID < 50399
280: static zval *Transliterator_read_property( zval *object, zval *member, int type TSRMLS_DC ) /* {{{ */
281: #else
282: static zval *Transliterator_read_property( zval *object, zval *member, int type,
283: const struct _zend_literal *key TSRMLS_DC ) /* {{{ */
284: #endif
285: {
286: zval *retval;
287:
288: TRANSLITERATOR_PROPERTY_HANDLER_PROLOG;
289:
290: if( ( type != BP_VAR_R && type != BP_VAR_IS ) &&
291: ( zend_binary_strcmp( "id", sizeof( "id" ) - 1,
292: Z_STRVAL_P( member ), Z_STRLEN_P( member ) ) == 0 ) )
293: {
294: php_error_docref0( NULL TSRMLS_CC, E_WARNING, "The property \"id\" is read-only" );
295: retval = &EG( uninitialized_zval );
296: }
297: else
298: {
299: #if PHP_VERSION_ID < 50399
300: retval = std_object_handlers.read_property( object, member, type TSRMLS_CC );
301: #else
302: retval = std_object_handlers.read_property( object, member, type, key TSRMLS_CC );
303: #endif
304: }
305:
306: TRANSLITERATOR_PROPERTY_HANDLER_EPILOG;
307:
308: return retval;
309: }
310:
311: /* }}} */
312:
313: /* {{{ write_property handler */
314: #if PHP_VERSION_ID < 50399
315: static void Transliterator_write_property( zval *object, zval *member, zval *value TSRMLS_DC )
316: #else
317: static void Transliterator_write_property( zval *object, zval *member, zval *value,
318: const struct _zend_literal *key TSRMLS_DC )
319: #endif
320: {
321: TRANSLITERATOR_PROPERTY_HANDLER_PROLOG;
322:
323: if( ( EG( scope ) != Transliterator_ce_ptr ) &&
324: ( zend_binary_strcmp( "id", sizeof( "id" ) - 1,
325: Z_STRVAL_P( member ), Z_STRLEN_P( member ) ) == 0 ) )
326: {
327: php_error_docref0( NULL TSRMLS_CC, E_WARNING, "The property \"id\" is read-only" );
328: }
329: else
330: {
331: #if PHP_VERSION_ID < 50399
332: std_object_handlers.write_property( object, member, value TSRMLS_CC );
333: #else
334: std_object_handlers.write_property( object, member, value, key TSRMLS_CC );
335: #endif
336: }
337:
338: TRANSLITERATOR_PROPERTY_HANDLER_EPILOG;
339: }
340: /* }}} */
341:
342: /*
343: * 'Transliterator' class registration structures & functions
344: */
345:
346: /* {{{ Transliterator methods arguments info */
347:
348: ZEND_BEGIN_ARG_INFO_EX( ainfo_trans_void, 0, 0, 0 )
349: ZEND_END_ARG_INFO()
350:
351: ZEND_BEGIN_ARG_INFO_EX( ainfo_trans_create, 0, 0, 1 )
352: ZEND_ARG_INFO( 0, id )
353: ZEND_ARG_INFO( 0, direction )
354: ZEND_END_ARG_INFO()
355:
356: ZEND_BEGIN_ARG_INFO_EX( ainfo_trans_create_from_rules, 0, 0, 1 )
357: ZEND_ARG_INFO( 0, rules )
358: ZEND_ARG_INFO( 0, direction )
359: ZEND_END_ARG_INFO()
360:
361: ZEND_BEGIN_ARG_INFO_EX( ainfo_trans_create_inverse, 0, 0, 1 )
362: ZEND_ARG_OBJ_INFO( 0, orig_trans, Transliterator, 0 )
363: ZEND_END_ARG_INFO()
364:
365: ZEND_BEGIN_ARG_INFO_EX( ainfo_trans_me_transliterate, 0, 0, 1 )
366: ZEND_ARG_INFO( 0, subject )
367: ZEND_ARG_INFO( 0, start )
368: ZEND_ARG_INFO( 0, end )
369: ZEND_END_ARG_INFO()
370:
371: ZEND_BEGIN_ARG_INFO_EX( ainfo_trans_error, 0, 0, 1 )
372: ZEND_ARG_OBJ_INFO( 0, trans, Transliterator, 0 )
373: ZEND_END_ARG_INFO()
374:
375: /* }}} */
376:
377: /* {{{ Transliterator_class_functions
378: * Every 'Transliterator' class method has an entry in this table
379: */
380: zend_function_entry Transliterator_class_functions[] = {
381: PHP_ME( Transliterator, __construct, ainfo_trans_void, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR | ZEND_ACC_FINAL )
382: PHP_ME_MAPPING( create, transliterator_create, ainfo_trans_create, ZEND_ACC_STATIC |ZEND_ACC_PUBLIC )
383: PHP_ME_MAPPING( createFromRules,transliterator_create_from_rules, ainfo_trans_create_from_rules, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC )
384: PHP_ME_MAPPING( createInverse, transliterator_create_inverse, ainfo_trans_void, ZEND_ACC_PUBLIC )
385: PHP_ME_MAPPING( listIDs, transliterator_list_ids, ainfo_trans_void, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC )
386: PHP_ME_MAPPING( transliterate, transliterator_transliterate, ainfo_trans_me_transliterate, ZEND_ACC_PUBLIC )
387: PHP_ME_MAPPING( getErrorCode, transliterator_get_error_code, ainfo_trans_void, ZEND_ACC_PUBLIC )
388: PHP_ME_MAPPING( getErrorMessage,transliterator_get_error_message, ainfo_trans_void, ZEND_ACC_PUBLIC )
389: PHP_FE_END
390: };
391: /* }}} */
392:
393: /* {{{ transliterator_register_Transliterator_class
394: * Initialize 'Transliterator' class
395: */
396: void transliterator_register_Transliterator_class( TSRMLS_D )
397: {
398: zend_class_entry ce;
399:
400: /* Create and register 'Transliterator' class. */
401: INIT_CLASS_ENTRY( ce, "Transliterator", Transliterator_class_functions );
402: ce.create_object = Transliterator_object_create;
403: Transliterator_ce_ptr = zend_register_internal_class( &ce TSRMLS_CC );
404: memcpy( &Transliterator_handlers, zend_get_std_object_handlers(),
405: sizeof Transliterator_handlers );
406: Transliterator_handlers.clone_obj = Transliterator_clone_obj;
407: Transliterator_handlers.get_property_ptr_ptr = Transliterator_get_property_ptr_ptr;
408: Transliterator_handlers.read_property = Transliterator_read_property;
409: Transliterator_handlers.write_property = Transliterator_write_property;
410:
411: /* Declare 'Transliterator' class properties */
412: if( !Transliterator_ce_ptr )
413: {
414: zend_error( E_ERROR,
415: "Transliterator: attempt to create properties "
416: "on a non-registered class." );
417: return;
418: }
419: zend_declare_property_null( Transliterator_ce_ptr,
420: "id", sizeof( "id" ) - 1, ZEND_ACC_PUBLIC TSRMLS_CC );
421:
422: /* constants are declared in transliterator_register_constants, called from MINIT */
423:
424: }
425: /* }}} */
426:
427: /*
428: * Local variables:
429: * tab-width: 4
430: * c-basic-offset: 4
431: * End:
432: * vim600: noet sw=4 ts=4 fdm=marker
433: * vim<600: noet sw=4 ts=4
434: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>