}
/*
- * 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;
}
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)
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;
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;
convert_to_double(pzv); \
break; \
case IS_BOOL: \
- convert_to_bool(pzv); \
+ convert_to_boolean(pzv); \
break; \
case IS_ARRAY: \
convert_to_array(pzv); \
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);