xref: /php-src/ext/intl/intl_data.h (revision 01b3fc03)
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    | https://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