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 | http://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 | Stanislav Malyshev <stas@zend.com> | 14 +----------------------------------------------------------------------+ 15 */ 16 17 #ifndef INTL_DATA_H 18 #define INTL_DATA_H 19 20 #include <unicode/utypes.h> 21 22 #include "intl_error.h" 23 24 /* Mock object to generalize error handling in sub-modules. 25 Sub-module data structures should always have error as first element 26 for this to work! 27 */ 28 typedef struct _intl_data { 29 intl_error error; 30 zend_object zo; 31 } intl_object; 32 33 #define INTL_METHOD_INIT_VARS(oclass, obj) \ 34 zval* object = NULL; \ 35 oclass##_object* obj = NULL; \ 36 intl_error_reset( NULL ); 37 38 #define INTL_DATA_ERROR(obj) (((intl_object *)(obj))->error) 39 #define INTL_DATA_ERROR_P(obj) (&(INTL_DATA_ERROR((obj)))) 40 #define INTL_DATA_ERROR_CODE(obj) INTL_ERROR_CODE(INTL_DATA_ERROR((obj))) 41 42 #define INTL_METHOD_FETCH_OBJECT(oclass, obj) \ 43 obj = Z_##oclass##_P( object ); \ 44 intl_error_reset( INTL_DATA_ERROR_P(obj) ); \ 45 46 /* Check status by error code, if error return false */ 47 #define INTL_CHECK_STATUS(err, msg) \ 48 intl_error_set_code( NULL, (err) ); \ 49 if( U_FAILURE((err)) ) \ 50 { \ 51 intl_error_set_custom_msg( NULL, msg, 0 ); \ 52 RETURN_FALSE; \ 53 } 54 55 /* Check status by error code, if error return null */ 56 #define INTL_CHECK_STATUS_OR_NULL(err, msg) \ 57 intl_error_set_code( NULL, (err) ); \ 58 if( U_FAILURE((err)) ) \ 59 { \ 60 intl_error_set_custom_msg( NULL, msg, 0 ); \ 61 RETURN_NULL(); \ 62 } 63 64 65 /* Check status in object, if error return false */ 66 #define INTL_METHOD_CHECK_STATUS(obj, msg) \ 67 intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((obj)) ); \ 68 if( U_FAILURE( INTL_DATA_ERROR_CODE((obj)) ) ) \ 69 { \ 70 intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg, 0 ); \ 71 RETURN_FALSE; \ 72 } 73 74 /* Check status in object, if error goto a label */ 75 #define INTL_METHOD_CHECK_STATUS_OR_GOTO(obj, msg, label) \ 76 intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((obj)) ); \ 77 if( U_FAILURE( INTL_DATA_ERROR_CODE((obj)) ) ) \ 78 { \ 79 intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg, 0 ); \ 80 RETVAL_FALSE; \ 81 goto label; \ 82 } 83 84 /* Check status in object, if error return null */ 85 #define INTL_METHOD_CHECK_STATUS_OR_NULL(obj, msg) \ 86 intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((obj)) ); \ 87 if( U_FAILURE( INTL_DATA_ERROR_CODE((obj)) ) ) \ 88 { \ 89 intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg, 0 ); \ 90 zval_ptr_dtor(return_value); \ 91 RETURN_NULL(); \ 92 } 93 94 /* Check status in object, if error return FAILURE */ 95 #define INTL_CTOR_CHECK_STATUS(obj, msg) \ 96 intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((obj)) ); \ 97 if( U_FAILURE( INTL_DATA_ERROR_CODE((obj)) ) ) \ 98 { \ 99 intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg, 0 ); \ 100 return FAILURE; \ 101 } 102 103 #define INTL_METHOD_RETVAL_UTF8(obj, ustring, ulen, free_it) \ 104 { \ 105 zend_string *u8str; \ 106 u8str = intl_convert_utf16_to_utf8(ustring, ulen, &INTL_DATA_ERROR_CODE((obj))); \ 107 if((free_it)) { \ 108 efree(ustring); \ 109 } \ 110 INTL_METHOD_CHECK_STATUS((obj), "Error converting value to UTF-8"); \ 111 RETVAL_NEW_STR(u8str); \ 112 } 113 114 #define INTL_MAX_LOCALE_LEN (ULOC_FULLNAME_CAPACITY-1) 115 116 #define INTL_CHECK_LOCALE_LEN(locale_len) \ 117 if((locale_len) > INTL_MAX_LOCALE_LEN) { \ 118 char *_msg; \ 119 spprintf(&_msg, 0, "Locale string too long, should be no longer than %d characters", INTL_MAX_LOCALE_LEN); \ 120 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, _msg, 1); \ 121 efree(_msg); \ 122 RETURN_NULL(); \ 123 } 124 125 #define INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len) \ 126 if((locale_len) > INTL_MAX_LOCALE_LEN) { \ 127 char *_msg; \ 128 spprintf(&_msg, 0, "Locale string too long, should be no longer than %d characters", INTL_MAX_LOCALE_LEN); \ 129 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, _msg, 1); \ 130 efree(_msg); \ 131 return FAILURE; \ 132 } 133 134 #endif // INTL_DATA_H 135