php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
resourcebundle_class.c
Go to the documentation of this file.
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: Hans-Peter Oeri (University of St.Gallen) <hp@oeri.ch> |
12 +----------------------------------------------------------------------+
13 */
14
15#include <stdlib.h>
16#include <unicode/ures.h>
17#include <unicode/uenum.h>
18
19#include <zend.h>
22#include <php.h>
23
24#include "php_intl.h"
25#include "intl_data.h"
26#include "intl_common.h"
27
32
34
35static zend_object_handlers ResourceBundle_object_handlers;
36
37/* {{{ ResourceBundle_object_free */
38static void ResourceBundle_object_free( zend_object *object )
39{
40 ResourceBundle_object *rb = php_intl_resourcebundle_fetch_object(object);
41
42 // only free local errors
44
45 if (rb->me) {
46 ures_close( rb->me );
47 }
48 if (rb->child) {
49 ures_close( rb->child );
50 }
51
53}
54/* }}} */
55
56/* {{{ ResourceBundle_object_create */
57static zend_object *ResourceBundle_object_create( zend_class_entry *ce )
58{
60
61 rb = zend_object_alloc(sizeof(ResourceBundle_object), ce);
62
63 zend_object_std_init( &rb->zend, ce );
65
67 rb->me = NULL;
68 rb->child = NULL;
69
70 return &rb->zend;
71}
72/* }}} */
73
74/* {{{ ResourceBundle_ctor */
75static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced)
76{
77 char *bundlename;
78 size_t bundlename_len = 0;
79 char *locale;
80 size_t locale_len = 0;
81 bool fallback = true;
82
83 zval *object = return_value;
85
87
89 Z_PARAM_STRING_OR_NULL(locale, locale_len)
90 Z_PARAM_STRING_OR_NULL(bundlename, bundlename_len)
92 Z_PARAM_BOOL(fallback)
94
95 if (error_handling != NULL) {
97 *error_handling_replaced = 1;
98 }
99
100 if (rb->me) {
101 zend_throw_error(NULL, "ResourceBundle object is already constructed");
102 return FAILURE;
103 }
104
106
107 if (locale == NULL) {
108 locale = (char *)intl_locale_get_default();
109 }
110
111 if (bundlename_len >= MAXPATHLEN) {
112 zend_argument_value_error(2, "is too long");
113 return FAILURE;
114 }
115
116 if (fallback) {
117 rb->me = ures_open(bundlename, locale, &INTL_DATA_ERROR_CODE(rb));
118 } else {
119 rb->me = ures_openDirect(bundlename, locale, &INTL_DATA_ERROR_CODE(rb));
120 }
121
122 INTL_CTOR_CHECK_STATUS(rb, "resourcebundle_ctor: Cannot load libICU resource bundle");
123
124 if (!fallback && (INTL_DATA_ERROR_CODE(rb) == U_USING_FALLBACK_WARNING ||
126 char *pbuf;
128 spprintf(&pbuf, 0, "resourcebundle_ctor: Cannot load libICU resource "
129 "'%s' without fallback from %s to %s",
130 bundlename ? bundlename : "(default data)", locale,
131 ures_getLocaleByType(
134 efree(pbuf);
135 return FAILURE;
136 }
137
138 return SUCCESS;
139}
140/* }}} */
141
142/* {{{ ResourceBundle object constructor */
144{
145 zend_error_handling error_handling;
146 bool error_handling_replaced = 0;
147
149 if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) {
150 if (!EG(exception)) {
151 zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0);
152 }
153 }
154 if (error_handling_replaced) {
155 zend_restore_error_handling(&error_handling);
156 }
157}
158/* }}} */
159
160/* {{{ */
169/* }}} */
170
171/* {{{ resourcebundle_array_fetch */
172static zval *resource_bundle_array_fetch(
173 zend_object *object, zend_string *offset_str, zend_long offset_int,
174 zval *return_value, bool fallback, uint32_t offset_arg_num)
175{
176 int32_t index = 0;
177 char *key = NULL;
178 bool is_numeric = offset_str == NULL;
179 char *pbuf;
181
182 rb = php_intl_resourcebundle_fetch_object(object);
185
186 if (offset_str) {
187 if (UNEXPECTED(ZSTR_LEN(offset_str) == 0)) {
188 if (offset_arg_num) {
190 } else {
191 zend_value_error("Offset must not be empty");
192 }
193 return NULL;
194 }
195 key = ZSTR_VAL(offset_str);
196 rb->child = ures_getByKey(rb->me, key, rb->child, &INTL_DATA_ERROR_CODE(rb) );
197 } else {
198 if (UNEXPECTED(offset_int < (zend_long)INT32_MIN || offset_int > (zend_long)INT32_MAX)) {
199 if (offset_arg_num) {
200 zend_argument_value_error(offset_arg_num, "index must be between %d and %d", INT32_MIN, INT32_MAX);
201 } else {
202 zend_value_error("Index must be between %d and %d", INT32_MIN, INT32_MAX);
203 }
204 return NULL;
205 }
206 index = (int32_t)offset_int;
207 rb->child = ures_getByIndex(rb->me, index, rb->child, &INTL_DATA_ERROR_CODE(rb));
208 }
209
211 if (U_FAILURE(INTL_DATA_ERROR_CODE(rb))) {
212 if (is_numeric) {
213 spprintf( &pbuf, 0, "Cannot load resource element %d", index );
214 } else {
215 spprintf( &pbuf, 0, "Cannot load resource element '%s'", key );
216 }
218 efree(pbuf);
219 RETVAL_NULL();
220 return return_value;
221 }
222
224 UErrorCode icuerror;
225 const char * locale = ures_getLocaleByType( rb->me, ULOC_ACTUAL_LOCALE, &icuerror );
226 if (is_numeric) {
227 spprintf(&pbuf, 0, "Cannot load element %d without fallback from to %s", index, locale);
228 } else {
229 spprintf(&pbuf, 0, "Cannot load element '%s' without fallback from to %s", key, locale);
230 }
232 efree(pbuf);
233 RETVAL_NULL();
234 return return_value;
235 }
236
238 return return_value;
239}
240/* }}} */
241
242/* {{{ resourcebundle_array_get */
244{
245 if (offset == NULL) {
246 zend_throw_error(NULL, "Cannot apply [] to ResourceBundle object");
247 return NULL;
248 }
249
251 if (Z_TYPE_P(offset) == IS_LONG) {
252 return resource_bundle_array_fetch(object, /* offset_str */ NULL, Z_LVAL_P(offset), rv, /* fallback */ true, /* arg_num */ 0);
253 } else if (Z_TYPE_P(offset) == IS_STRING) {
254 return resource_bundle_array_fetch(object, Z_STR_P(offset), /* offset_int */ 0, rv, /* fallback */ true, /* arg_num */ 0);
255 } else {
257 return NULL;
258 }
259}
260/* }}} */
261
262/* {{{ Get resource identified by numerical index or key name. */
264{
265 bool fallback = true;
266 zend_object *resource_bundle = NULL;
267 zend_string *offset_str = NULL;
268 zend_long offset_long = 0;
269
272 Z_PARAM_STR_OR_LONG(offset_str, offset_long)
274 Z_PARAM_BOOL(fallback)
276
277 zval *retval = resource_bundle_array_fetch(resource_bundle, offset_str, offset_long, return_value, fallback, /* arg_num */ 2);
278 if (!retval) {
280 }
281}
282/* }}} */
283
285{
286 bool fallback = true;
287 zend_string *offset_str = NULL;
288 zend_long offset_long = 0;
289
291 Z_PARAM_STR_OR_LONG(offset_str, offset_long)
293 Z_PARAM_BOOL(fallback)
295
296 zval *retval = resource_bundle_array_fetch(Z_OBJ_P(ZEND_THIS), offset_str, offset_long, return_value, fallback, /* arg_num */ 1);
297 if (!retval) {
299 }
300}
301/* }}} */
302
303/* {{{ resourcebundle_array_count */
304static zend_result resourcebundle_array_count(zend_object *object, zend_long *count)
305{
306 ResourceBundle_object *rb = php_intl_resourcebundle_fetch_object(object);
307
308 if (rb->me == NULL) {
310 "Found unconstructed ResourceBundle", 0);
311 return 0;
312 }
313
314 *count = ures_getSize( rb->me );
315
316 return SUCCESS;
317}
318/* }}} */
319
320/* {{{ Get resources count */
322{
323 int32_t len;
325
328 }
329
331
332 len = ures_getSize( rb->me );
333 RETURN_LONG( len );
334}
335
336/* {{{ Get available locales from ResourceBundle name */
338{
339 char * bundlename;
340 size_t bundlename_len = 0;
341 const char * entry;
342 int entry_len;
343 UEnumeration *icuenum;
344 UErrorCode icuerror = U_ZERO_ERROR;
345
347
349 Z_PARAM_STRING(bundlename, bundlename_len)
351
352 if (bundlename_len >= MAXPATHLEN) {
353 zend_argument_value_error(1, "is too long");
355 }
356
357 if(bundlename_len == 0) {
358 // fetch default locales list
359 bundlename = NULL;
360 }
361
362 icuenum = ures_openAvailableLocales( bundlename, &icuerror );
363 INTL_CHECK_STATUS(icuerror, "Cannot fetch locales list");
364
365 uenum_reset( icuenum, &icuerror );
366 INTL_CHECK_STATUS(icuerror, "Cannot iterate locales list");
367
369 while ((entry = uenum_next( icuenum, &entry_len, &icuerror ))) {
370 add_next_index_stringl( return_value, (char *) entry, entry_len);
371 }
372 uenum_close( icuenum );
373}
374/* }}} */
375
376/* {{{ Get text description for ResourceBundle's last error code. */
391/* }}} */
392
393/* {{{ Get text description for ResourceBundle's last error. */
395{
396 zend_string* message = NULL;
398
400 &object, ResourceBundle_ce_ptr ) == FAILURE )
401 {
403 }
404
405 rb = Z_INTL_RESOURCEBUNDLE_P( object );
407 RETURN_STR(message);
408}
409/* }}} */
410
416
417/* {{{ resourcebundle_register_class
418 * Initialize 'ResourceBundle' class
419 */
421{
422 ResourceBundle_ce_ptr = register_class_ResourceBundle(zend_ce_aggregate, zend_ce_countable);
423 ResourceBundle_ce_ptr->create_object = ResourceBundle_object_create;
424 ResourceBundle_ce_ptr->default_object_handlers = &ResourceBundle_object_handlers;
426
427 ResourceBundle_object_handlers = std_object_handlers;
428 ResourceBundle_object_handlers.offset = XtOffsetOf(ResourceBundle_object, zend);
429 ResourceBundle_object_handlers.clone_obj = NULL; /* ICU ResourceBundle has no clone implementation */
430 ResourceBundle_object_handlers.free_obj = ResourceBundle_object_free;
431 ResourceBundle_object_handlers.read_dimension = resourcebundle_array_get;
432 ResourceBundle_object_handlers.count_elements = resourcebundle_array_count;
433}
434/* }}} */
size_t len
Definition apprentice.c:174
bool exception
Definition assert.c:30
count(Countable|array $value, int $mode=COUNT_NORMAL)
is_numeric(mixed $value)
const ULOC_ACTUAL_LOCALE
const U_USING_DEFAULT_WARNING
const U_ILLEGAL_ARGUMENT_ERROR
const U_ZERO_ERROR
const U_USING_FALLBACK_WARNING
zend_ffi_type * type
Definition ffi.c:3812
zend_long offset
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
zend_class_entry * IntlException_ce_ptr
Definition intl_error.c:30
#define INTL_DATA_ERROR_P(obj)
Definition intl_data.h:39
#define INTL_CTOR_CHECK_STATUS(obj, msg)
Definition intl_data.h:95
#define INTL_CHECK_STATUS(err, msg)
Definition intl_data.h:47
#define INTL_DATA_ERROR_CODE(obj)
Definition intl_data.h:40
#define INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len)
Definition intl_data.h:125
void intl_errors_set_custom_msg(intl_error *err, const char *msg, int copyMsg)
Definition intl_error.c:187
void intl_error_init(intl_error *err)
Definition intl_error.c:66
void intl_errors_set(intl_error *err, UErrorCode code, const char *msg, int copyMsg)
Definition intl_error.c:169
void intl_error_reset(intl_error *err)
Definition intl_error.c:78
void intl_errors_reset(intl_error *err)
Definition intl_error.c:177
void intl_error_set_code(intl_error *err, UErrorCode err_code)
Definition intl_error.c:141
void intl_errors_set_code(intl_error *err, UErrorCode err_code)
Definition intl_error.c:197
zend_string * intl_error_get_message(intl_error *err)
Definition intl_error.c:116
#define PHP_FUNCTION
Definition php.h:364
#define PHP_METHOD
Definition php.h:365
const char * intl_locale_get_default(void)
Definition php_intl.c:91
resourcebundle_get(ResourceBundle $bundle, string|int $index, bool $fallback=true)
resourcebundle_get_error_message(ResourceBundle $bundle)
resourcebundle_create(?string $locale, ?string $bundle, bool $fallback=true)
resourcebundle_get_error_code(ResourceBundle $bundle)
resourcebundle_locales(string $bundle)
resourcebundle_count(ResourceBundle $bundle)
unsigned char key[REFLECTION_KEY_LEN]
void resourcebundle_extract_value(zval *return_value, ResourceBundle_object *source)
zval * resourcebundle_array_get(zend_object *object, zval *offset, int type, zval *rv)
zend_class_entry * ResourceBundle_ce_ptr
void resourcebundle_register_class(void)
#define RESOURCEBUNDLE_METHOD_FETCH_OBJECT
#define RESOURCEBUNDLE_METHOD_INIT_VARS
#define Z_INTL_RESOURCEBUNDLE_P(zv)
zend_object_iterator * resourcebundle_get_iterator(zend_class_entry *ce, zval *object, int byref)
zval rv
Definition session.c:1024
#define spprintf
Definition spprintf.h:29
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
Definition zend.c:1772
ZEND_API ZEND_COLD void zend_value_error(const char *format,...)
Definition zend.c:1849
ZEND_API ZEND_COLD void zend_illegal_container_offset(const zend_string *container, const zval *offset, int type)
Definition zend.c:1802
#define INTERNAL_FUNCTION_PARAMETERS
Definition zend.h:49
@ EH_THROW
Definition zend.h:433
ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, zend_class_entry *exception_class, zend_error_handling *current)
Definition zend_API.c:5242
ZEND_API void zend_restore_error_handling(zend_error_handling *saved)
Definition zend_API.c:5253
#define INTERNAL_FUNCTION_PARAM_PASSTHRU
Definition zend.h:50
ZEND_API zend_result add_next_index_stringl(zval *arg, const char *str, size_t length)
Definition zend_API.c:2195
ZEND_API zend_result object_init_ex(zval *arg, zend_class_entry *class_type)
Definition zend_API.c:1849
ZEND_API void object_properties_init(zend_object *object, zend_class_entry *class_type)
Definition zend_API.c:1688
ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num)
Definition zend_API.c:443
ZEND_API zend_result zend_parse_method_parameters(uint32_t num_args, zval *this_ptr, const char *type_spec,...)
Definition zend_API.c:1314
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:433
#define ZEND_NUM_ARGS()
Definition zend_API.h:530
#define ZEND_PARSE_PARAMETERS_END()
Definition zend_API.h:1641
#define ZEND_PARSE_PARAMETERS_NONE()
Definition zend_API.h:1623
#define RETURN_NULL()
Definition zend_API.h:1036
#define Z_PARAM_OPTIONAL
Definition zend_API.h:1667
#define Z_PARAM_STRING(dest, dest_len)
Definition zend_API.h:2071
#define ZEND_PARSE_PARAMETERS_END_EX(failure)
Definition zend_API.h:1630
#define Z_PARAM_STRING_OR_NULL(dest, dest_len)
Definition zend_API.h:2074
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
Definition zend_API.h:1620
#define RETURN_LONG(l)
Definition zend_API.h:1037
#define RETVAL_NULL()
Definition zend_API.h:1010
#define RETURN_THROWS()
Definition zend_API.h:1060
#define Z_PARAM_OBJ_OF_CLASS(dest, _ce)
Definition zend_API.h:1997
#define RETURN_STR(s)
Definition zend_API.h:1039
#define ZEND_THIS
Definition zend_API.h:523
#define Z_PARAM_STR_OR_LONG(dest_str, dest_long)
Definition zend_API.h:2165
#define Z_PARAM_BOOL(dest)
Definition zend_API.h:1726
#define getThis()
Definition zend_API.h:526
#define array_init(arg)
Definition zend_API.h:537
#define efree(ptr)
Definition zend_alloc.h:155
struct _zval_struct zval
ZEND_API ZEND_COLD zend_object * zend_throw_exception(zend_class_entry *exception_ce, const char *message, zend_long code)
#define EG(v)
ZEND_API zend_class_entry * zend_ce_countable
ZEND_API zend_class_entry * zend_ce_aggregate
ZEND_API zend_result zend_create_internal_iterator_zval(zval *return_value, zval *obj)
int32_t zend_long
Definition zend_long.h:42
struct _zend_string zend_string
ZEND_API const zend_object_handlers std_object_handlers
ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class_entry *ce)
ZEND_API void zend_object_std_dtor(zend_object *object)
#define XtOffsetOf(s_type, field)
#define UNEXPECTED(condition)
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
#define ZVAL_DEREF(z)
#define IS_STRING
Definition zend_types.h:606
#define Z_OBJ_P(zval_p)
Definition zend_types.h:990
#define Z_STR_P(zval_p)
Definition zend_types.h:972
@ FAILURE
Definition zend_types.h:61
#define IS_LONG
Definition zend_types.h:604
ZEND_RESULT_CODE zend_result
Definition zend_types.h:64
struct _zend_object_handlers zend_object_handlers
Definition zend_types.h:88
#define Z_LVAL_P(zval_p)
Definition zend_types.h:966
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
#define MAXPATHLEN
zval retval
zval * return_value
object