intl/converter in line w/ intl error handling

This commit is contained in:
Gustavo Lopes 2013-01-29 18:57:42 +01:00
parent a721fe2b22
commit 1da67fc65e
3 changed files with 113 additions and 34 deletions

View File

@ -51,8 +51,7 @@ static inline void php_converter_throw_failure(php_converter_object *objval, UEr
vsnprintf(message, sizeof(message), format, vargs); vsnprintf(message, sizeof(message), format, vargs);
va_end(vargs); va_end(vargs);
intl_error_set_code(err, error TSRMLS_CC); intl_errors_set(err, error, message, 1 TSRMLS_CC);
intl_error_set_custom_msg(err, message, 1 TSRMLS_CC);
} }
/* }}} */ /* }}} */
@ -433,8 +432,11 @@ static void php_converter_do_set_encoding(UConverter *cnv, INTERNAL_FUNCTION_PAR
int enc_len; int enc_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &enc, &enc_len) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &enc, &enc_len) == FAILURE) {
return; intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "Bad arguments, "
"expected one string argument", 0 TSRMLS_CC);
RETURN_FALSE;
} }
intl_errors_reset(&objval->error TSRMLS_CC);
RETURN_BOOL(php_converter_set_encoding(objval, &(objval->src), enc, enc_len TSRMLS_CC)); RETURN_BOOL(php_converter_set_encoding(objval, &(objval->src), enc, enc_len TSRMLS_CC));
} }
@ -458,21 +460,23 @@ static PHP_METHOD(UConverter, setDestinationEncoding) {
ZEND_BEGIN_ARG_INFO_EX(php_converter_get_encoding_arginfo, 0, ZEND_RETURN_VALUE, 0) ZEND_BEGIN_ARG_INFO_EX(php_converter_get_encoding_arginfo, 0, ZEND_RETURN_VALUE, 0)
ZEND_END_ARG_INFO(); ZEND_END_ARG_INFO();
static void php_converter_do_get_encoding(php_converter_object *objval, UConverter *cnv, INTERNAL_FUNCTION_PARAMETERS) { static void php_converter_do_get_encoding(php_converter_object *objval, UConverter *cnv, INTERNAL_FUNCTION_PARAMETERS) {
UErrorCode error = U_ZERO_ERROR;
const char *name; const char *name;
if (ZEND_NUM_ARGS() > 0) { if (zend_parse_parameters_none() == FAILURE) {
WRONG_PARAM_COUNT; intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "Expected no arguments", 0 TSRMLS_CC);
RETURN_FALSE;
} }
intl_errors_reset(&objval->error TSRMLS_CC);
if (!cnv) { if (!cnv) {
RETURN_NULL(); RETURN_NULL();
} }
name = ucnv_getName(cnv, &error); name = ucnv_getName(cnv, &objval->error.code);
if (U_FAILURE(error)) { if (U_FAILURE(objval->error.code)) {
THROW_UFAILURE(objval, "ucnv_getName()", error); THROW_UFAILURE(objval, "ucnv_getName()", objval->error.code);
RETURN_NULL(); RETURN_FALSE;
} }
RETURN_STRING(name, 1); RETURN_STRING(name, 1);
@ -497,21 +501,22 @@ static PHP_METHOD(UConverter, getDestinationEncoding) {
ZEND_BEGIN_ARG_INFO_EX(php_converter_get_type_arginfo, 0, ZEND_RETURN_VALUE, 0) ZEND_BEGIN_ARG_INFO_EX(php_converter_get_type_arginfo, 0, ZEND_RETURN_VALUE, 0)
ZEND_END_ARG_INFO(); ZEND_END_ARG_INFO();
static void php_converter_do_get_type(php_converter_object *objval, UConverter *cnv, INTERNAL_FUNCTION_PARAMETERS) { static void php_converter_do_get_type(php_converter_object *objval, UConverter *cnv, INTERNAL_FUNCTION_PARAMETERS) {
UErrorCode error = U_ZERO_ERROR;
UConverterType t; UConverterType t;
if (ZEND_NUM_ARGS() > 0) { if (zend_parse_parameters_none() == FAILURE) {
WRONG_PARAM_COUNT; intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "Expected no arguments", 0 TSRMLS_CC);
RETURN_FALSE;
} }
intl_errors_reset(&objval->error TSRMLS_CC);
if (!cnv) { if (!cnv) {
RETURN_NULL(); RETURN_NULL();
} }
t = ucnv_getType(cnv); t = ucnv_getType(cnv);
if (U_FAILURE(error)) { if (U_FAILURE(objval->error.code)) {
THROW_UFAILURE(objval, "ucnv_getType", error); THROW_UFAILURE(objval, "ucnv_getType", objval->error.code);
RETURN_NULL(); RETURN_FALSE;
} }
RETURN_LONG(t); RETURN_LONG(t);
@ -568,8 +573,12 @@ static PHP_METHOD(UConverter, __construct) {
char *dest = src; char *dest = src;
int dest_len = src_len; int dest_len = src_len;
intl_error_reset(NULL TSRMLS_CC);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!", if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!",
&dest, &dest_len, &src, &src_len) == FAILURE) { &dest, &dest_len, &src, &src_len) == FAILURE) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"UConverter::__construct(): bad arguments", 0 TSRMLS_CC);
return; return;
} }
@ -591,8 +600,11 @@ static PHP_METHOD(UConverter, setSubstChars) {
int chars_len, ret = 1; int chars_len, ret = 1;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &chars, &chars_len) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &chars, &chars_len) == FAILURE) {
return; intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"UConverter::setSubstChars(): bad arguments", 0 TSRMLS_CC);
RETURN_FALSE;
} }
intl_errors_reset(&objval->error TSRMLS_CC);
if (objval->src) { if (objval->src) {
UErrorCode error = U_ZERO_ERROR; UErrorCode error = U_ZERO_ERROR;
@ -603,6 +615,7 @@ static PHP_METHOD(UConverter, setSubstChars) {
} }
} else { } else {
php_converter_throw_failure(objval, U_INVALID_STATE_ERROR TSRMLS_CC, "Source Converter has not been initialized yet"); php_converter_throw_failure(objval, U_INVALID_STATE_ERROR TSRMLS_CC, "Source Converter has not been initialized yet");
ret = 0;
} }
if (objval->dest) { if (objval->dest) {
@ -614,6 +627,7 @@ static PHP_METHOD(UConverter, setSubstChars) {
} }
} else { } else {
php_converter_throw_failure(objval, U_INVALID_STATE_ERROR TSRMLS_CC, "Destination Converter has not been initialized yet"); php_converter_throw_failure(objval, U_INVALID_STATE_ERROR TSRMLS_CC, "Destination Converter has not been initialized yet");
ret = 0;
} }
RETURN_BOOL(ret); RETURN_BOOL(ret);
@ -630,6 +644,13 @@ static PHP_METHOD(UConverter, getSubstChars) {
int8_t chars_len = sizeof(chars); int8_t chars_len = sizeof(chars);
UErrorCode error = U_ZERO_ERROR; UErrorCode error = U_ZERO_ERROR;
if (zend_parse_parameters_none() == FAILURE) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"UConverter::getSubstChars(): expected no arguments", 0 TSRMLS_CC);
RETURN_FALSE;
}
intl_errors_reset(&objval->error TSRMLS_CC);
if (!objval->src) { if (!objval->src) {
RETURN_NULL(); RETURN_NULL();
} }
@ -640,7 +661,7 @@ static PHP_METHOD(UConverter, getSubstChars) {
ucnv_getSubstChars(objval->src, chars, &chars_len, &error); ucnv_getSubstChars(objval->src, chars, &chars_len, &error);
if (U_FAILURE(error)) { if (U_FAILURE(error)) {
THROW_UFAILURE(objval, "ucnv_getSubstChars", error); THROW_UFAILURE(objval, "ucnv_getSubstChars", error);
RETURN_NULL(); RETURN_FALSE;
} }
RETURN_STRINGL(chars, chars_len, 1); RETURN_STRINGL(chars, chars_len, 1);
@ -717,8 +738,11 @@ static PHP_METHOD(UConverter, reasonText) {
long reason; long reason;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &reason) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &reason) == FAILURE) {
return; intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"UConverter::reasonText(): bad arguments", 0 TSRMLS_CC);
RETURN_FALSE;
} }
intl_error_reset(NULL TSRMLS_CC);
switch (reason) { switch (reason) {
UCNV_REASON_CASE(UNASSIGNED) UCNV_REASON_CASE(UNASSIGNED)
@ -729,7 +753,7 @@ static PHP_METHOD(UConverter, reasonText) {
UCNV_REASON_CASE(CLONE) UCNV_REASON_CASE(CLONE)
default: default:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown UConverterCallbackReason: %ld", reason); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown UConverterCallbackReason: %ld", reason);
RETURN_NULL(); RETURN_FALSE;
} }
} }
/* }}} */ /* }}} */
@ -748,8 +772,11 @@ static PHP_METHOD(UConverter, convert) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b",
&str, &str_len, &reverse) == FAILURE) { &str, &str_len, &reverse) == FAILURE) {
return; intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"UConverter::convert(): bad arguments", 0 TSRMLS_CC);
RETURN_FALSE;
} }
intl_errors_reset(&objval->error TSRMLS_CC);
if (php_converter_do_convert(reverse ? objval->src : objval->dest, if (php_converter_do_convert(reverse ? objval->src : objval->dest,
&dest, &dest_len, &dest, &dest_len,
@ -758,7 +785,7 @@ static PHP_METHOD(UConverter, convert) {
objval TSRMLS_CC)) { objval TSRMLS_CC)) {
RETURN_STRINGL(dest, dest_len, 0); RETURN_STRINGL(dest, dest_len, 0);
} else { } else {
RETURN_NULL(); RETURN_FALSE;
} }
} }
/* }}} */ /* }}} */
@ -779,8 +806,11 @@ static PHP_METHOD(UConverter, transcode) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|a!", if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|a!",
&str, &str_len, &dest, &dest_len, &src, &src_len, &options) == FAILURE) { &str, &str_len, &dest, &dest_len, &src, &src_len, &options) == FAILURE) {
return; intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"UConverter::transcode(): bad arguments", 0 TSRMLS_CC);
RETURN_FALSE;
} }
intl_error_reset(NULL TSRMLS_CC);
if (php_converter_set_encoding(NULL, &src_cnv, src, src_len TSRMLS_CC) && if (php_converter_set_encoding(NULL, &src_cnv, src, src_len TSRMLS_CC) &&
php_converter_set_encoding(NULL, &dest_cnv, dest, dest_len TSRMLS_CC)) { php_converter_set_encoding(NULL, &dest_cnv, dest, dest_len TSRMLS_CC)) {
@ -812,7 +842,10 @@ static PHP_METHOD(UConverter, transcode) {
if (U_FAILURE(error)) { if (U_FAILURE(error)) {
THROW_UFAILURE(NULL, "transcode", error); THROW_UFAILURE(NULL, "transcode", error);
RETVAL_FALSE;
} }
} else {
RETVAL_FALSE;
} }
if (src_cnv) { if (src_cnv) {
@ -830,8 +863,10 @@ ZEND_END_ARG_INFO();
static PHP_METHOD(UConverter, getErrorCode) { static PHP_METHOD(UConverter, getErrorCode) {
php_converter_object *objval = CONV_GET(getThis()); php_converter_object *objval = CONV_GET(getThis());
if (ZEND_NUM_ARGS() > 0) { if (zend_parse_parameters_none() == FAILURE) {
WRONG_PARAM_COUNT; intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"UConverter::getErrorCode(): expected no arguments", 0 TSRMLS_CC);
RETURN_FALSE;
} }
RETURN_LONG(intl_error_get_code(&(objval->error) TSRMLS_CC)); RETURN_LONG(intl_error_get_code(&(objval->error) TSRMLS_CC));
@ -845,8 +880,10 @@ static PHP_METHOD(UConverter, getErrorMessage) {
php_converter_object *objval = CONV_GET(getThis()); php_converter_object *objval = CONV_GET(getThis());
char *message = intl_error_get_message(&(objval->error) TSRMLS_CC); char *message = intl_error_get_message(&(objval->error) TSRMLS_CC);
if (ZEND_NUM_ARGS() > 0) { if (zend_parse_parameters_none() == FAILURE) {
WRONG_PARAM_COUNT; intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"UConverter::getErrorMessage(): expected no arguments", 0 TSRMLS_CC);
RETURN_FALSE;
} }
if (message) { if (message) {
@ -861,7 +898,15 @@ static PHP_METHOD(UConverter, getErrorMessage) {
ZEND_BEGIN_ARG_INFO_EX(php_converter_getavailable_arginfo, 0, ZEND_RETURN_VALUE, 0) ZEND_BEGIN_ARG_INFO_EX(php_converter_getavailable_arginfo, 0, ZEND_RETURN_VALUE, 0)
ZEND_END_ARG_INFO(); ZEND_END_ARG_INFO();
static PHP_METHOD(UConverter, getAvailable) { static PHP_METHOD(UConverter, getAvailable) {
int32_t i, count = ucnv_countAvailable(); int32_t i,
count = ucnv_countAvailable();
if (zend_parse_parameters_none() == FAILURE) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"UConverter::getErrorMessage(): expected no arguments", 0 TSRMLS_CC);
RETURN_FALSE;
}
intl_error_reset(NULL TSRMLS_CC);
array_init(return_value); array_init(return_value);
for(i = 0; i < count; i++) { for(i = 0; i < count; i++) {
@ -882,13 +927,16 @@ static PHP_METHOD(UConverter, getAliases) {
uint16_t i, count; uint16_t i, count;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
return; intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"UConverter::getAliases(): bad arguments", 0 TSRMLS_CC);
RETURN_FALSE;
} }
intl_error_reset(NULL TSRMLS_CC);
count = ucnv_countAliases(name, &error); count = ucnv_countAliases(name, &error);
if (U_FAILURE(error)) { if (U_FAILURE(error)) {
THROW_UFAILURE(NULL, "ucnv_countAliases", error); THROW_UFAILURE(NULL, "ucnv_countAliases", error);
return; RETURN_FALSE;
} }
array_init(return_value); array_init(return_value);
@ -911,6 +959,13 @@ ZEND_END_ARG_INFO();
static PHP_METHOD(UConverter, getStandards) { static PHP_METHOD(UConverter, getStandards) {
uint16_t i, count; uint16_t i, count;
if (zend_parse_parameters_none() == FAILURE) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"UConverter::getStandards(): expected no arguments", 0 TSRMLS_CC);
RETURN_FALSE;
}
intl_error_reset(NULL TSRMLS_CC);
array_init(return_value); array_init(return_value);
count = ucnv_countStandards(); count = ucnv_countStandards();
for(i = 0; i < count; i++) { for(i = 0; i < count; i++) {
@ -1011,13 +1066,23 @@ static zend_object_value php_converter_clone_object(zval *object TSRMLS_DC) {
php_converter_object *objval, *oldobj = (php_converter_object*)zend_objects_get_address(object TSRMLS_CC); php_converter_object *objval, *oldobj = (php_converter_object*)zend_objects_get_address(object TSRMLS_CC);
zend_object_value retval = php_converter_object_ctor(Z_OBJCE_P(object), &objval TSRMLS_CC); zend_object_value retval = php_converter_object_ctor(Z_OBJCE_P(object), &objval TSRMLS_CC);
UErrorCode error = U_ZERO_ERROR; UErrorCode error = U_ZERO_ERROR;
intl_errors_reset(&oldobj->error TSRMLS_CC);
objval->src = ucnv_safeClone(oldobj->src, NULL, NULL, &error); objval->src = ucnv_safeClone(oldobj->src, NULL, NULL, &error);
if (U_SUCCESS(error)) { if (U_SUCCESS(error)) {
error = U_ZERO_ERROR; error = U_ZERO_ERROR;
objval->dest = ucnv_safeClone(oldobj->dest, NULL, NULL, &error); objval->dest = ucnv_safeClone(oldobj->dest, NULL, NULL, &error);
} }
if (U_FAILURE(error)) { if (U_FAILURE(error)) {
char *err_msg;
THROW_UFAILURE(oldobj, "ucnv_safeClone", error); THROW_UFAILURE(oldobj, "ucnv_safeClone", error);
err_msg = intl_error_get_message(&oldobj->error TSRMLS_CC);
zend_throw_exception(NULL, err_msg, 0 TSRMLS_CC);
efree(err_msg);
return retval;
} }
/* Update contexts for converter error handlers */ /* Update contexts for converter error handlers */

View File

@ -0,0 +1,14 @@
--TEST--
Basic UConverter::convert() usage
--INI--
intl.error_level = E_WARNING
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
--FILE--
<?php
$c = new UConverter('utf-8', "\x80");
var_dump($c);
--EXPECTF--
Warning: UConverter::__construct(): ucnv_open() returned error 4: U_FILE_ACCESS_ERROR in %s on line %d
object(UConverter)#%d (0) {
}

View File

@ -9,13 +9,13 @@ intl.use_exceptions=false
foreach(array('?','','??') as $subst) { foreach(array('?','','??') as $subst) {
$opts = array('to_subst' => $subst); $opts = array('to_subst' => $subst);
$ret = UConverter::transcode("This is an ascii string", 'ascii', 'utf-8', $opts); $ret = UConverter::transcode("This is an ascii string", 'ascii', 'utf-8', $opts);
if ($ret === NULL) { if ($ret === FALSE) {
echo "Error: ", intl_get_error_message(), "\n"; echo "Error: ", intl_get_error_message(), "\n";
} else { } else {
var_dump($ret); var_dump($ret);
} }
$ret = UConverter::transcode("Snowman: (\xE2\x98\x83)", 'ascii', 'utf-8', $opts); $ret = UConverter::transcode("Snowman: (\xE2\x98\x83)", 'ascii', 'utf-8', $opts);
if ($ret === NULL) { if ($ret === FALSE) {
echo "Error: ", intl_get_error_message(), "\n"; echo "Error: ", intl_get_error_message(), "\n";
} else { } else {
var_dump($ret); var_dump($ret);