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