From: Andrei Zmievski Date: Thu, 18 Aug 2005 22:33:23 +0000 (+0000) Subject: - Implement zend_codepoint_to_uchar(). X-Git-Tag: PRE_NEW_OCI8_EXTENSION~156 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fe71ae29d98d98ef65b89c15bab58d6b3db57957;p=php - Implement zend_codepoint_to_uchar(). - Rename and fix zend_get_unified_string_type() so that it does not allow mixing of binary and Unicode types. --- diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 9422bb865b..248441b732 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2928,30 +2928,40 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, char *n } /* - * Return the most precise string type out of the list. - * If none of the types are string types, IS_STRING is returned. - * Binary > Unicode > string. + * Return the string type that all the passed in types should be converted to. + * If none of the types are string types, IS_UNICODE or IS_STRING is returned, + * depending on the Unicode semantics switch. + * Binary and Unicode types cannot be mixed, so we return -1 (or 255 since it's + * uchar) */ -ZEND_API zend_uchar zend_get_best_string_type(int num_args, ...) +ZEND_API zend_uchar zend_get_unified_string_type(int num_args TSRMLS_DC, ...) { va_list ap; - int best_type = IS_STRING; + int best_type = UG(unicode) ? IS_UNICODE : IS_STRING; + zend_bool seen_unicode = 0; int type; - if (num_args <= 0) return -1; + if (num_args <= 0) return (zend_uchar)-1; va_start(ap, num_args); while (num_args--) { type = va_arg(ap, int); if (type == IS_BINARY) { best_type = IS_BINARY; - break; - } else if (type == IS_UNICODE && best_type == IS_STRING) { - best_type = IS_UNICODE; + } else if (type == IS_UNICODE) { + seen_unicode = 1; + if (best_type == IS_STRING) { + best_type = IS_UNICODE; + } } } va_end(ap); + /* We do not allow mixing binary and Unicode types */ + if (best_type == IS_BINARY && seen_unicode) { + return (zend_uchar)-1; + } + return best_type; } diff --git a/Zend/zend_API.h b/Zend/zend_API.h index c5c54ddeb5..6a5ee07893 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -235,7 +235,7 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, char *n ZEND_API zend_class_entry *zend_get_class_entry(zval *zobject TSRMLS_DC); ZEND_API int zend_get_object_classname(zval *object, char **class_name, zend_uint *class_name_len TSRMLS_DC); -ZEND_API zend_uchar zend_get_best_string_type(int num_args, ...); +ZEND_API zend_uchar zend_get_unified_string_type(int num_args TSRMLS_DC, ...); #define getThis() (this_ptr) diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index d5fa434e89..1cdea5aac6 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -68,7 +68,7 @@ ZEND_API long zend_u_strtol(const UChar *nptr, UChar **endptr, int base); ZEND_API double zend_u_strtod(const UChar *nptr, UChar **endptr); END_EXTERN_C() -static inline zend_bool is_numeric_string(char *str, int length, long *lval, double *dval, zend_bool allow_errors) +static inline zend_uchar is_numeric_string(char *str, int length, long *lval, double *dval, zend_bool allow_errors) { long local_lval; double local_dval; @@ -131,7 +131,7 @@ static inline zend_bool is_numeric_string(char *str, int length, long *lval, dou return 0; } -static inline zend_bool is_numeric_unicode(UChar *str, int32_t length, long *lval, double *dval, zend_bool allow_errors) +static inline zend_uchar is_numeric_unicode(UChar *str, int32_t length, long *lval, double *dval, zend_bool allow_errors) { int32_t local_lval; double local_dval; @@ -320,7 +320,7 @@ END_EXTERN_C() convert_to_double(pzv); \ break; \ case IS_BOOL: \ - convert_to_bool(pzv); \ + convert_to_boolean(pzv); \ break; \ case IS_ARRAY: \ convert_to_array(pzv); \ diff --git a/Zend/zend_unicode.h b/Zend/zend_unicode.h index 950dc7c1fd..6de5538936 100644 --- a/Zend/zend_unicode.h +++ b/Zend/zend_unicode.h @@ -71,6 +71,24 @@ static inline UChar32 zend_get_codepoint_at(UChar *str, int32_t length, int32_t return c; } +/* + * Convert a single codepoint to UChar sequence (1 or 2). + * The UChar buffer is assumed to be large enough. + */ +static inline int zend_codepoint_to_uchar(UChar32 codepoint, UChar *buf) +{ + if (U_IS_BMP(codepoint)) { + *buf++ = (UChar) codepoint; + return 1; + } else if (codepoint <= UCHAR_MAX_VALUE) { + *buf++ = (UChar) U16_LEAD(codepoint); + *buf++ = (UChar) U16_TRAIL(codepoint); + return 2; + } else { + return 0; + } +} + #define ZEND_U_CONVERTER(c) ((c)?(c):UG(fallback_encoding_conv)) #define USTR_FREE(ustr) do { if (ustr) { efree(ustr); } } while (0);