Variant c_Collator::t_compare(CStrRef str1, CStrRef str2) { INSTANCE_METHOD_INJECTION_BUILTIN(Collator, Collator::compare); if (!m_ucoll) { raise_warning("compare called on uninitialized Collator object"); return 0; } UChar* ustr1 = NULL; UChar* ustr2 = NULL; int ustr1_len = 0; int ustr2_len = 0; m_errcode.clear(); intl_convert_utf8_to_utf16(&ustr1, &ustr1_len, str1.data(), str1.length(), &(m_errcode.code)); if (U_FAILURE(m_errcode.code)) { free(ustr1); return false; } intl_convert_utf8_to_utf16(&ustr2, &ustr2_len, str2.data(), str2.length(), &(m_errcode.code)); if (U_FAILURE(m_errcode.code)) { free(ustr1); free(ustr2); return false; } int64 ret = ucol_strcoll(m_ucoll, ustr1, ustr1_len, ustr2, ustr2_len); free(ustr1); free(ustr2); return ret; }
/* {{{ */ static void msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) { char* locale; char* pattern; int locale_len = 0, pattern_len = 0; UChar* spattern = NULL; int spattern_len = 0; zval* object; MessageFormatter_object* mfo; intl_error_reset( NULL TSRMLS_CC ); object = return_value; /* Parse parameters. */ if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "ss", &locale, &locale_len, &pattern, &pattern_len ) == FAILURE ) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "msgfmt_create: unable to parse input parameters", 0 TSRMLS_CC ); zval_dtor(return_value); RETURN_NULL(); } INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value); MSG_FORMAT_METHOD_FETCH_OBJECT; /* Convert pattern (if specified) to UTF-16. */ if(pattern && pattern_len) { intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(mfo)); INTL_CTOR_CHECK_STATUS(mfo, "msgfmt_create: error converting pattern to UTF-16"); } else { spattern_len = 0; spattern = NULL; } if(locale_len == 0) { locale = INTL_G(default_locale); } #ifdef MSG_FORMAT_QUOTE_APOS if(msgformat_fix_quotes(&spattern, &spattern_len, &INTL_DATA_ERROR_CODE(mfo)) != SUCCESS) { INTL_CTOR_CHECK_STATUS(mfo, "msgfmt_create: error converting pattern to quote-friendly format"); } #endif if ((mfo)->mf_data.orig_format) { msgformat_data_free(&mfo->mf_data TSRMLS_CC); } (mfo)->mf_data.orig_format = estrndup(pattern, pattern_len); (mfo)->mf_data.orig_format_len = pattern_len; /* Create an ICU message formatter. */ MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, locale, NULL, &INTL_DATA_ERROR_CODE(mfo)); if(spattern) { efree(spattern); } INTL_CTOR_CHECK_STATUS(mfo, "msgfmt_create: message formatter creation failed"); }
/* {{{ * Internal function which calls the udat_parse * param int store_error acts like a boolean * if set to 1 - store any error encountered in the parameter parse_error * if set to 0 - no need to store any error encountered in the parameter parse_error */ static void internal_parse_to_timestamp(IntlDateFormatter_object *dfo, char* text_to_parse, int32_t text_len, int32_t *parse_pos, zval *return_value) { double result = 0; UDate timestamp =0; UChar* text_utf16 = NULL; int32_t text_utf16_len = 0; /* Convert timezone to UTF-16. */ intl_convert_utf8_to_utf16(&text_utf16, &text_utf16_len, text_to_parse, text_len, &INTL_DATA_ERROR_CODE(dfo)); INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" ); timestamp = udat_parse( DATE_FORMAT_OBJECT(dfo), text_utf16, text_utf16_len, parse_pos, &INTL_DATA_ERROR_CODE(dfo)); if( text_utf16 ){ efree(text_utf16); } INTL_METHOD_CHECK_STATUS( dfo, "Date parsing failed" ); /* Since return is in sec. */ result = (double)timestamp / U_MILLIS_PER_SECOND; if(result > LONG_MAX || result < -LONG_MAX) { ZVAL_DOUBLE(return_value, result<0?ceil(result):floor(result)); } else { ZVAL_LONG(return_value, (zend_long)result); } }
static void php_intl_idn_to(INTERNAL_FUNCTION_PARAMETERS, const char *domain, int32_t domain_len, uint32_t option, int mode) { UChar* ustring = NULL; int ustring_len = 0; UErrorCode status; char *converted_utf8; size_t converted_utf8_len; UChar converted[MAXPATHLEN]; int32_t converted_ret_len; /* convert the string to UTF-16. */ status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&ustring, &ustring_len, domain, domain_len, &status); if (U_FAILURE(status)) { intl_error_set_code(NULL, status); /* Set error messages. */ intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 ); if (ustring) { efree(ustring); } RETURN_FALSE; } else { UParseError parse_error; status = U_ZERO_ERROR; if (mode == INTL_IDN_TO_ASCII) { converted_ret_len = uidna_IDNToASCII(ustring, ustring_len, converted, MAXPATHLEN, (int32_t)option, &parse_error, &status); } else { converted_ret_len = uidna_IDNToUnicode(ustring, ustring_len, converted, MAXPATHLEN, (int32_t)option, &parse_error, &status); } efree(ustring); if (U_FAILURE(status)) { intl_error_set( NULL, status, "idn_to_ascii: cannot convert to ASCII", 0 ); RETURN_FALSE; } status = U_ZERO_ERROR; intl_convert_utf16_to_utf8(&converted_utf8, &converted_utf8_len, converted, converted_ret_len, &status); if (U_FAILURE(status)) { /* Set global error code. */ intl_error_set_code(NULL, status); /* Set error messages. */ intl_error_set_custom_msg( NULL, "Error converting output string to UTF-8", 0 ); efree(converted_utf8); RETURN_FALSE; } } /* return the allocated string, not a duplicate */ RETVAL_STRINGL(converted_utf8, converted_utf8_len); //???? efree(converted_utf8); }
static String intl_convert_str_utf8_to_utf16(CStrRef utf8_str, UErrorCode * status) { UChar* ustr = nullptr; int ustr_len = 0; intl_convert_utf8_to_utf16(&ustr, &ustr_len, utf8_str.data(), utf8_str.length(), status); if (U_FAILURE(*status)) { return (const char *)(L""); } return String((char*)ustr, UBYTES(ustr_len), AttachString); }
Variant c_Normalizer::ti_isnormalized(const char* cls , CStrRef input, int64 form /* = q_Normalizer___FORM_C */) { STATIC_METHOD_INJECTION_BUILTIN(Normalizer, Normalizer::isnormalized); s_intl_error->m_error.clear(); switch (form) { case UNORM_NFD: case UNORM_NFKD: case UNORM_NFC: case UNORM_NFKC: break; default: s_intl_error->m_error.code = U_ILLEGAL_ARGUMENT_ERROR; s_intl_error->m_error.custom_error_message = "normalizer_isnormalized: illegal normalization form"; return null; } /* First convert the string to UTF-16. */ UChar* uinput = NULL; int uinput_len = 0; UErrorCode status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&uinput, &uinput_len, input.data(), input.size(), &status); if (U_FAILURE(status)) { s_intl_error->m_error.code = status; s_intl_error->m_error.custom_error_message = "Error converting string to UTF-16."; free(uinput); return false; } /* test string */ UBool uret = unorm_isNormalizedWithOptions(uinput, uinput_len, (UNormalizationMode)form, (int32_t)0, &status); free(uinput); /* Bail out if an unexpected error occured. */ if (U_FAILURE(status)) { s_intl_error->m_error.code = status; s_intl_error->m_error.custom_error_message = "Error testing if string is the given normalization form."; return false; } return uret; }
Variant c_Normalizer::ti_isnormalized(const String& input, int64_t form /* = q_Normalizer$$FORM_C */) { s_intl_error->clearError(); switch (form) { case UNORM_NFD: case UNORM_NFKD: case UNORM_NFC: case UNORM_NFKC: break; default: s_intl_error->setError(U_ILLEGAL_ARGUMENT_ERROR, "normalizer_isnormalized: " "illegal normalization form"); return uninit_null(); } /* First convert the string to UTF-16. */ UChar* uinput = NULL; int uinput_len = 0; UErrorCode status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&uinput, &uinput_len, input.data(), input.size(), &status); if (U_FAILURE(status)) { s_intl_error->setError(status, "Error converting string to UTF-16."); free(uinput); return false; } /* test string */ UBool uret = unorm_isNormalizedWithOptions(uinput, uinput_len, (UNormalizationMode)form, (int32_t)0, &status); free(uinput); /* Bail out if an unexpected error occured. */ if (U_FAILURE(status)) { s_intl_error->setError(status, "Error testing if string is the given " "normalization form."); return false; } return uret; }
/* {{{ */ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_constructor) { const char* locale; char* pattern = NULL; size_t locale_len = 0, pattern_len = 0; zend_long style; UChar* spattern = NULL; int32_t spattern_len = 0; int zpp_flags = is_constructor ? ZEND_PARSE_PARAMS_THROW : 0; FORMATTER_METHOD_INIT_VARS; /* Parse parameters. */ if( zend_parse_parameters_ex( zpp_flags, ZEND_NUM_ARGS(), "sl|s", &locale, &locale_len, &style, &pattern, &pattern_len ) == FAILURE ) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "numfmt_create: unable to parse input parameters", 0 ); return FAILURE; } INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); object = return_value; FORMATTER_METHOD_FETCH_OBJECT_NO_CHECK; /* Convert pattern (if specified) to UTF-16. */ if(pattern && pattern_len) { intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(nfo)); INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: error converting pattern to UTF-16"); } if(locale_len == 0) { locale = intl_locale_get_default(); } /* Create an ICU number formatter. */ FORMATTER_OBJECT(nfo) = unum_open(style, spattern, spattern_len, locale, NULL, &INTL_DATA_ERROR_CODE(nfo)); if(spattern) { efree(spattern); } INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: number formatter creation failed"); return SUCCESS; }
/* {{{ */ static void numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) { char* locale; char* pattern = NULL; int locale_len = 0, pattern_len = 0; long style; UChar* spattern = NULL; int spattern_len = 0; FORMATTER_METHOD_INIT_VARS; /* Parse parameters. */ if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "sl|s", &locale, &locale_len, &style, &pattern, &pattern_len ) == FAILURE ) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "numfmt_create: unable to parse input parameters", 0 TSRMLS_CC ); zval_dtor(return_value); RETURN_NULL(); } INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value); object = return_value; FORMATTER_METHOD_FETCH_OBJECT; /* Convert pattern (if specified) to UTF-16. */ if(pattern && pattern_len) { intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(nfo)); INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: error converting pattern to UTF-16"); } if(locale_len == 0) { locale = INTL_G(default_locale); } /* Create an ICU number formatter. */ FORMATTER_OBJECT(nfo) = unum_open(style, spattern, spattern_len, locale, NULL, &INTL_DATA_ERROR_CODE(nfo)); if(spattern) { efree(spattern); } INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: number formatter creation failed"); }
/* {{{ * Internal function which calls the udat_parseCalendar */ static void internal_parse_to_localtime(IntlDateFormatter_object *dfo, char* text_to_parse, int32_t text_len, int32_t *parse_pos, zval *return_value) { UCalendar *parsed_calendar = NULL; UChar* text_utf16 = NULL; int32_t text_utf16_len = 0; zend_long isInDST = 0; /* Convert timezone to UTF-16. */ intl_convert_utf8_to_utf16(&text_utf16, &text_utf16_len, text_to_parse, text_len, &INTL_DATA_ERROR_CODE(dfo)); INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" ); parsed_calendar = (UCalendar *)udat_getCalendar(DATE_FORMAT_OBJECT(dfo)); udat_parseCalendar( DATE_FORMAT_OBJECT(dfo), parsed_calendar, text_utf16, text_utf16_len, parse_pos, &INTL_DATA_ERROR_CODE(dfo)); if (text_utf16) { efree(text_utf16); } INTL_METHOD_CHECK_STATUS( dfo, "Date parsing failed" ); array_init( return_value ); /* Add entries from various fields of the obtained parsed_calendar */ add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_SECOND, CALENDAR_SEC); add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_MINUTE, CALENDAR_MIN); add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_HOUR_OF_DAY, CALENDAR_HOUR); add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_YEAR, CALENDAR_YEAR); add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_MONTH, CALENDAR_MDAY); add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_WEEK, CALENDAR_WDAY); add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_YEAR, CALENDAR_YDAY); add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_MONTH, CALENDAR_MON); /* Is in DST? */ isInDST = ucal_inDaylightTime(parsed_calendar , &INTL_DATA_ERROR_CODE(dfo)); INTL_METHOD_CHECK_STATUS( dfo, "Date parsing - localtime failed : while checking if currently in DST." ); add_assoc_long( return_value, CALENDAR_ISDST,(isInDST==1?1:0)); }
Variant c_Normalizer::ti_normalize(const char* cls , CStrRef input, int64 form /* = q_Normalizer___FORM_C */) { STATIC_METHOD_INJECTION_BUILTIN(Normalizer, Normalizer::normalize); s_intl_error->m_error.clear(); int expansion_factor = 1; switch(form) { case UNORM_NONE: case UNORM_NFC: case UNORM_NFKC: break; case UNORM_NFD: case UNORM_NFKD: expansion_factor = 3; break; default: s_intl_error->m_error.code = U_ILLEGAL_ARGUMENT_ERROR; s_intl_error->m_error.custom_error_message = "normalizer_normalize: illegal normalization form"; return null; } /* First convert the string to UTF-16. */ UChar* uinput = NULL; int uinput_len = 0; UErrorCode status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&uinput, &uinput_len, input.data(), input.size(), &status); if (U_FAILURE(status)) { s_intl_error->m_error.code = status; s_intl_error->m_error.custom_error_message = "Error converting string to UTF-16."; free(uinput); return null; } /* Allocate memory for the destination buffer for normalization */ int uret_len = uinput_len * expansion_factor; UChar *uret_buf = (UChar*)malloc((uret_len + 1) * sizeof(UChar)); /* normalize */ int size_needed = unorm_normalize(uinput, uinput_len, (UNormalizationMode)form, (int32_t) 0, uret_buf, uret_len, &status); /* Bail out if an unexpected error occured. * (U_BUFFER_OVERFLOW_ERROR means that *target buffer is not large enough). * (U_STRING_NOT_TERMINATED_WARNING usually means that the input string * is empty). */ if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR && status != U_STRING_NOT_TERMINATED_WARNING) { free(uret_buf); free(uinput); return null; } if (size_needed > uret_len) { /* realloc does not seem to work properly - memory is corrupted * uret_buf = eurealloc(uret_buf, size_needed + 1); */ free(uret_buf); uret_buf = (UChar*)malloc((size_needed + 1) * sizeof(UChar)); uret_len = size_needed; status = U_ZERO_ERROR; /* try normalize again */ size_needed = unorm_normalize( uinput, uinput_len, (UNormalizationMode)form, (int32_t) 0, uret_buf, uret_len, &status); /* Bail out if an unexpected error occured. */ if (U_FAILURE(status)) { /* Set error messages. */ s_intl_error->m_error.code = status; s_intl_error->m_error.custom_error_message = "Error normalizing string"; free(uret_buf); free(uinput); return null; } } free(uinput); /* the buffer we actually used */ uret_len = size_needed; /* Convert normalized string from UTF-16 to UTF-8. */ char* ret_buf = NULL; int ret_len = 0; intl_convert_utf16_to_utf8(&ret_buf, &ret_len, uret_buf, uret_len, &status); free(uret_buf); if (U_FAILURE(status)) { s_intl_error->m_error.code = status; s_intl_error->m_error.custom_error_message = "normalizer_normalize: error converting normalized text UTF-8"; return null; } return String(ret_buf, ret_len, AttachString); }
bool c_Collator::t_sortwithsortkeys(VRefParam arr) { INSTANCE_METHOD_INJECTION_BUILTIN(Collator, Collator::sortwithsortkeys); char* sortKeyBuf = NULL; /* buffer to store sort keys */ int32_t sortKeyBufSize = DEF_SORT_KEYS_BUF_SIZE; /* buffer size */ ptrdiff_t sortKeyBufOffset = 0; /* pos in buffer to store sort key */ int32_t sortKeyLen = 0; /* the length of currently processing key */ int32_t bufLeft = 0; int32_t bufIncrement = 0; /* buffer to store 'indexes' which will be passed to 'qsort' */ collator_sort_key_index_t* sortKeyIndxBuf = NULL; int32_t sortKeyIndxBufSize = DEF_SORT_KEYS_INDX_BUF_SIZE; int32_t sortKeyIndxSize = sizeof( collator_sort_key_index_t ); int32_t sortKeyCount = 0; int32_t j = 0; /* tmp buffer to hold current processing string in utf-16 */ UChar* utf16_buf = NULL; /* the length of utf16_buf */ int utf16_buf_size = DEF_UTF16_BUF_SIZE; /* length of converted string */ int utf16_len = 0; m_errcode.clear(); s_intl_error->m_error.clear(); /* * Sort specified array. */ if (!arr.isArray()) { return true; } Array hash = arr.toArray(); if (hash.size() == 0) { return true; } /* Create bufers */ sortKeyBuf = (char*)calloc(sortKeyBufSize, sizeof(char)); sortKeyIndxBuf = (collator_sort_key_index_t*)malloc(sortKeyIndxBufSize); utf16_buf = (UChar*)malloc(utf16_buf_size); /* Iterate through input hash and create a sort key for each value. */ for (ssize_t pos = hash->iter_begin(); pos != ArrayData::invalid_index; pos = hash->iter_advance(pos)) { /* Convert current hash item from UTF-8 to UTF-16LE and save the result * to utf16_buf. */ utf16_len = utf16_buf_size; /* Process string values only. */ Variant val(hash->getValue(pos)); if (val.isString()) { String str = val.toString(); intl_convert_utf8_to_utf16(&utf16_buf, &utf16_len, str.data(), str.size(), &(m_errcode.code)); if (U_FAILURE(m_errcode.code)) { m_errcode.custom_error_message = "Sort with sort keys failed"; if (utf16_buf) { free(utf16_buf); } free(sortKeyIndxBuf); free(sortKeyBuf); return false; } } else { /* Set empty string */ utf16_len = 0; utf16_buf[utf16_len] = 0; } if ((utf16_len + 1) > utf16_buf_size) { utf16_buf_size = utf16_len + 1; } /* Get sort key, reallocating the buffer if needed. */ bufLeft = sortKeyBufSize - sortKeyBufOffset; sortKeyLen = ucol_getSortKey(m_ucoll, utf16_buf, utf16_len, (uint8_t*)sortKeyBuf + sortKeyBufOffset, bufLeft); /* check for sortKeyBuf overflow, increasing its size of the buffer if needed */ if (sortKeyLen > bufLeft) { bufIncrement = ( sortKeyLen > DEF_SORT_KEYS_BUF_INCREMENT ) ? sortKeyLen : DEF_SORT_KEYS_BUF_INCREMENT; sortKeyBufSize += bufIncrement; bufLeft += bufIncrement; sortKeyBuf = (char*)realloc(sortKeyBuf, sortKeyBufSize); sortKeyLen = ucol_getSortKey(m_ucoll, utf16_buf, utf16_len, (uint8_t*)sortKeyBuf + sortKeyBufOffset, bufLeft); } /* check sortKeyIndxBuf overflow, increasing its size of the buffer if needed */ if ((sortKeyCount + 1) * sortKeyIndxSize > sortKeyIndxBufSize) { bufIncrement = (sortKeyIndxSize > DEF_SORT_KEYS_INDX_BUF_INCREMENT) ? sortKeyIndxSize : DEF_SORT_KEYS_INDX_BUF_INCREMENT; sortKeyIndxBufSize += bufIncrement; sortKeyIndxBuf = (collator_sort_key_index_t*)realloc(sortKeyIndxBuf, sortKeyIndxBufSize); } sortKeyIndxBuf[sortKeyCount].key = (char*)sortKeyBufOffset; sortKeyIndxBuf[sortKeyCount].valPos = pos; sortKeyBufOffset += sortKeyLen; ++sortKeyCount; } /* update ptrs to point to valid keys. */ for( j = 0; j < sortKeyCount; j++ ) sortKeyIndxBuf[j].key = sortKeyBuf + (ptrdiff_t)sortKeyIndxBuf[j].key; /* sort it */ zend_qsort(sortKeyIndxBuf, sortKeyCount, sortKeyIndxSize, collator_cmp_sort_keys, NULL); /* for resulting hash we'll assign new hash keys rather then reordering */ Array sortedHash = Array::Create(); for (j = 0; j < sortKeyCount; j++) { sortedHash.append(hash->getValue(sortKeyIndxBuf[j].valPos)); } /* Save sorted hash into return variable. */ arr = sortedHash; if (utf16_buf) free(utf16_buf); free(sortKeyIndxBuf); free(sortKeyBuf); return true; }
/* {{{ */ static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) { zval *object; const char *locale_str; size_t locale_len = 0; Locale locale; zend_long date_type = 0; zend_long time_type = 0; zval *calendar_zv = NULL; Calendar *calendar = NULL; zend_long calendar_type; bool calendar_owned; zval *timezone_zv = NULL; TimeZone *timezone = NULL; bool explicit_tz; char* pattern_str = NULL; size_t pattern_str_len = 0; UChar* svalue = NULL; /* UTF-16 pattern_str */ int32_t slength = 0; IntlDateFormatter_object* dfo; intl_error_reset(NULL); object = return_value; /* Parse parameters. */ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sll|zzs", &locale_str, &locale_len, &date_type, &time_type, &timezone_zv, &calendar_zv, &pattern_str, &pattern_str_len) == FAILURE) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: " "unable to parse input parameters", 0); Z_OBJ_P(return_value) = NULL; return; } INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value); if (locale_len == 0) { locale_str = intl_locale_get_default(); } locale = Locale::createFromName(locale_str); DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK; if (DATE_FORMAT_OBJECT(dfo) != NULL) { intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: cannot call constructor twice", 0); return; } /* process calendar */ if (datefmt_process_calendar_arg(calendar_zv, locale, "datefmt_create", INTL_DATA_ERROR_P(dfo), calendar, calendar_type, calendar_owned) == FAILURE) { goto error; } /* process timezone */ explicit_tz = timezone_zv != NULL && Z_TYPE_P(timezone_zv) != IS_NULL; if (explicit_tz || calendar_owned ) { //we have an explicit time zone or a non-object calendar timezone = timezone_process_timezone_argument(timezone_zv, INTL_DATA_ERROR_P(dfo), "datefmt_create"); if (timezone == NULL) { goto error; } } /* Convert pattern (if specified) to UTF-16. */ if (pattern_str && pattern_str_len > 0) { intl_convert_utf8_to_utf16(&svalue, &slength, pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo)); if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { /* object construction -> only set global error */ intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: " "error converting pattern to UTF-16", 0); goto error; } } if (pattern_str && pattern_str_len > 0) { DATE_FORMAT_OBJECT(dfo) = udat_open(UDAT_IGNORE, UDAT_IGNORE, locale_str, NULL, 0, svalue, slength, &INTL_DATA_ERROR_CODE(dfo)); } else { DATE_FORMAT_OBJECT(dfo) = udat_open((UDateFormatStyle)time_type, (UDateFormatStyle)date_type, locale_str, NULL, 0, svalue, slength, &INTL_DATA_ERROR_CODE(dfo)); } if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { DateFormat *df = (DateFormat*)DATE_FORMAT_OBJECT(dfo); if (calendar_owned) { df->adoptCalendar(calendar); calendar_owned = false; } else { df->setCalendar(*calendar); } if (timezone != NULL) { df->adoptTimeZone(timezone); } } else { intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date " "formatter creation failed", 0); goto error; } /* Set the class variables */ dfo->date_type = date_type; dfo->time_type = time_type; dfo->calendar = calendar_type; dfo->requested_locale = estrdup(locale_str); error: if (svalue) { efree(svalue); } if (timezone != NULL && DATE_FORMAT_OBJECT(dfo) == NULL) { delete timezone; } if (calendar != NULL && calendar_owned) { delete calendar; } if (U_FAILURE(intl_error_get_code(NULL))) { /* free_object handles partially constructed instances fine */ Z_OBJ_P(return_value) = NULL; } }
static Variant php_intl_idn_to(const String& domain, int64_t options, IdnVariant idn_variant, VRefParam idna_info, int mode) { UChar* ustring = NULL; int ustring_len = 0; UErrorCode status; char *converted_utf8 = NULL; int32_t converted_utf8_len; UChar* converted = NULL; int32_t converted_ret_len; if (idn_variant != INTL_IDN_VARIANT_2003) { #ifdef HAVE_46_API if (idn_variant == INTL_IDN_VARIANT_UTS46) { return php_intl_idn_to_46(domain, options, idn_variant, ref(idna_info), mode); } #endif return false; } // Convert the string to UTF-16 status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&ustring, &ustring_len, (char*)domain.data(), domain.size(), &status); if (U_FAILURE(status)) { free(ustring); return false; } // Call the appropriate IDN function int converted_len = (ustring_len > 1) ? ustring_len : 1; for (;;) { UParseError parse_error; status = U_ZERO_ERROR; converted = (UChar*)malloc(sizeof(UChar)*converted_len); // If the malloc failed, bail out if (!converted) { free(ustring); return false; } if (mode == INTL_IDN_TO_ASCII) { converted_ret_len = uidna_IDNToASCII(ustring, ustring_len, converted, converted_len, (int32_t)options, &parse_error, &status); } else { converted_ret_len = uidna_IDNToUnicode(ustring, ustring_len, converted, converted_len, (int32_t)options, &parse_error, &status); } if (status != U_BUFFER_OVERFLOW_ERROR) break; // If we have a buffer overflow error, try again with a larger buffer free(converted); converted = NULL; converted_len = converted_len * 2; } free(ustring); if (U_FAILURE(status)) { free(converted); return false; } // Convert the string back to UTF-8 status = U_ZERO_ERROR; intl_convert_utf16_to_utf8(&converted_utf8, &converted_utf8_len, converted, converted_ret_len, &status); free(converted); if (U_FAILURE(status)) { free(converted_utf8); return false; } // Return the string return String(converted_utf8, converted_utf8_len, AttachString); }
static Variant php_intl_idn_to(CStrRef domain, VRefParam errorcode, int mode) { long option = 0; UChar* ustring = NULL; int ustring_len = 0; UErrorCode status; char *converted_utf8 = NULL; int32_t converted_utf8_len; UChar* converted = NULL; int32_t converted_ret_len; // Convert the string to UTF-16 status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&ustring, &ustring_len, (char*)domain.data(), domain.size(), &status); if (U_FAILURE(status)) { free(ustring); errorcode = status; return false; } // Call the appropriate IDN function int converted_len = (ustring_len > 1) ? ustring_len : 1; for (;;) { UParseError parse_error; status = U_ZERO_ERROR; converted = (UChar*)malloc(sizeof(UChar)*converted_len); // If the malloc failed, bail out if (!converted) { free(ustring); errorcode = U_MEMORY_ALLOCATION_ERROR; return false; } if (mode == INTL_IDN_TO_ASCII) { converted_ret_len = uidna_IDNToASCII(ustring, ustring_len, converted, converted_len, (int32_t)option, &parse_error, &status); } else { converted_ret_len = uidna_IDNToUnicode(ustring, ustring_len, converted, converted_len, (int32_t)option, &parse_error, &status); } if (status != U_BUFFER_OVERFLOW_ERROR) break; // If we have a buffer overflow error, try again with a larger buffer free(converted); converted = NULL; converted_len = converted_len * 2; } free(ustring); if (U_FAILURE(status)) { free(converted); errorcode = status; return false; } // Convert the string back to UTF-8 status = U_ZERO_ERROR; intl_convert_utf16_to_utf8(&converted_utf8, &converted_utf8_len, converted, converted_ret_len, &status); free(converted); if (U_FAILURE(status)) { free(converted_utf8); errorcode = status; return false; } // Return the string return String(converted_utf8, converted_utf8_len, AttachString); }
/* {{{ grapheme_strpos_utf16 - strrpos using utf16*/ int grapheme_strpos_utf16(unsigned char *haystack, int32_t haystack_len, unsigned char*needle, int32_t needle_len, int32_t offset, int32_t *puchar_pos, int f_ignore_case TSRMLS_DC) { UChar *uhaystack, *puhaystack, *uneedle; int32_t uhaystack_len, uneedle_len; int ret_pos; unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; UBreakIterator* bi; UErrorCode status; *puchar_pos = -1; /* convert the strings to UTF-16. */ uhaystack = NULL; uhaystack_len = 0; status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&uhaystack, &uhaystack_len, (char *) haystack, haystack_len, &status ); if ( U_FAILURE( status ) ) { /* Set global error code. */ intl_error_set_code( NULL, status TSRMLS_CC ); /* Set error messages. */ intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 TSRMLS_CC ); efree( uhaystack ); return -1; } /* get a pointer to the haystack taking into account the offset */ bi = NULL; status = U_ZERO_ERROR; bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status TSRMLS_CC ); puhaystack = grapheme_get_haystack_offset(bi, uhaystack, uhaystack_len, offset); uhaystack_len = (uhaystack_len - ( puhaystack - uhaystack)); if ( NULL == puhaystack ) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_strpos: Offset not contained in string", 1 TSRMLS_CC ); efree( uhaystack ); ubrk_close (bi); return -1; } if ( f_ignore_case ) { grapheme_intl_case_fold(&uhaystack, &puhaystack, &uhaystack_len, &status ); } uneedle = NULL; uneedle_len = 0; status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&uneedle, &uneedle_len, (char *) needle, needle_len, &status ); if ( U_FAILURE( status ) ) { /* Set global error code. */ intl_error_set_code( NULL, status TSRMLS_CC ); /* Set error messages. */ intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 TSRMLS_CC ); efree( uhaystack ); efree( uneedle ); ubrk_close (bi); return -1; } if ( f_ignore_case ) { grapheme_intl_case_fold(&uneedle, &uneedle, &uneedle_len, &status ); } ret_pos = grapheme_memnstr_grapheme(bi, puhaystack, uneedle, uneedle_len, puhaystack + uhaystack_len ); *puchar_pos = ubrk_current(bi); efree( uhaystack ); efree( uneedle ); ubrk_close (bi); return ret_pos; }
/* {{{ grapheme_strrpos_utf16 - strrpos using utf16 */ int grapheme_strrpos_utf16(unsigned char *haystack, int32_t haystack_len, unsigned char*needle, int32_t needle_len, int32_t offset, int f_ignore_case TSRMLS_DC) { UChar *uhaystack, *puhaystack, *uhaystack_end, *uneedle; int32_t uhaystack_len, uneedle_len; UErrorCode status; unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; UBreakIterator* bi = NULL; int ret_pos, pos; /* convert the strings to UTF-16. */ uhaystack = NULL; uhaystack_len = 0; status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&uhaystack, &uhaystack_len, (char *) haystack, haystack_len, &status ); if ( U_FAILURE( status ) ) { /* Set global error code. */ intl_error_set_code( NULL, status TSRMLS_CC ); /* Set error messages. */ intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 TSRMLS_CC ); efree( uhaystack ); return -1; } if ( f_ignore_case ) { grapheme_intl_case_fold(&uhaystack, &uhaystack, &uhaystack_len, &status ); } /* get a pointer to the haystack taking into account the offset */ bi = NULL; status = U_ZERO_ERROR; bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status TSRMLS_CC ); puhaystack = grapheme_get_haystack_offset(bi, uhaystack, uhaystack_len, offset); if ( NULL == puhaystack ) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_strpos: Offset not contained in string", 1 TSRMLS_CC ); efree( uhaystack ); ubrk_close (bi); return -1; } uneedle = NULL; uneedle_len = 0; status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&uneedle, &uneedle_len, (char *) needle, needle_len, &status ); if ( U_FAILURE( status ) ) { /* Set global error code. */ intl_error_set_code( NULL, status TSRMLS_CC ); /* Set error messages. */ intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 TSRMLS_CC ); efree( uhaystack ); efree( uneedle ); ubrk_close (bi); return -1; } if ( f_ignore_case ) { grapheme_intl_case_fold(&uneedle, &uneedle, &uneedle_len, &status ); } ret_pos = -1; /* -1 represents 'not found' */ /* back up until there's needle_len characters to compare */ uhaystack_end = uhaystack + uhaystack_len; pos = ubrk_last(bi); puhaystack = uhaystack + pos; while ( uhaystack_end - puhaystack < uneedle_len ) { pos = ubrk_previous(bi); if ( UBRK_DONE == pos ) { break; } puhaystack = uhaystack + pos; } /* is there enough haystack left to hold the needle? */ if ( ( uhaystack_end - puhaystack ) < uneedle_len ) { /* not enough, not found */ goto exit; } while ( UBRK_DONE != pos ) { if (!u_memcmp(uneedle, puhaystack, uneedle_len)) { /* needle_len - 1 in zend memnstr? */ /* does the grapheme in the haystack end at the same place as the last grapheme in the needle? */ if ( ubrk_isBoundary(bi, pos + uneedle_len) ) { /* found it, get grapheme count offset */ ret_pos = grapheme_count_graphemes(bi, uhaystack, pos); break; } /* set position back */ ubrk_isBoundary(bi, pos); } pos = ubrk_previous(bi); puhaystack = uhaystack + pos; } exit: efree( uhaystack ); efree( uneedle ); ubrk_close (bi); return ret_pos; }
/* {{{ grapheme_strpos_utf16 - strrpos using utf16*/ int32_t grapheme_strpos_utf16(char *haystack, size_t haystack_len, char *needle, size_t needle_len, int32_t offset, int32_t *puchar_pos, int f_ignore_case, int last) { UChar *uhaystack = NULL, *uneedle = NULL; int32_t uhaystack_len = 0, uneedle_len = 0, char_pos, ret_pos, offset_pos = 0; unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; UBreakIterator* bi = NULL; UErrorCode status; UStringSearch* src = NULL; UCollator *coll; if(puchar_pos) { *puchar_pos = -1; } /* convert the strings to UTF-16. */ status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&uhaystack, &uhaystack_len, haystack, haystack_len, &status ); STRPOS_CHECK_STATUS(status, "Error converting input string to UTF-16"); status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&uneedle, &uneedle_len, needle, needle_len, &status ); STRPOS_CHECK_STATUS(status, "Error converting needle string to UTF-16"); /* get a pointer to the haystack taking into account the offset */ status = U_ZERO_ERROR; bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status ); STRPOS_CHECK_STATUS(status, "Failed to get iterator"); status = U_ZERO_ERROR; ubrk_setText(bi, uhaystack, uhaystack_len, &status); STRPOS_CHECK_STATUS(status, "Failed to set up iterator"); status = U_ZERO_ERROR; src = usearch_open(uneedle, uneedle_len, uhaystack, uhaystack_len, "", bi, &status); STRPOS_CHECK_STATUS(status, "Error creating search object"); if(f_ignore_case) { coll = usearch_getCollator(src); status = U_ZERO_ERROR; ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_SECONDARY, &status); STRPOS_CHECK_STATUS(status, "Error setting collation strength"); usearch_reset(src); } if(offset != 0) { offset_pos = grapheme_get_haystack_offset(bi, offset); if(offset_pos == -1) { status = U_ILLEGAL_ARGUMENT_ERROR; STRPOS_CHECK_STATUS(status, "Invalid search offset"); } status = U_ZERO_ERROR; usearch_setOffset(src, offset_pos, &status); STRPOS_CHECK_STATUS(status, "Invalid search offset"); } if(last) { char_pos = usearch_last(src, &status); if(char_pos < offset_pos) { /* last one is beyound our start offset */ char_pos = USEARCH_DONE; } } else { char_pos = usearch_next(src, &status); } STRPOS_CHECK_STATUS(status, "Error looking up string"); if(char_pos != USEARCH_DONE && ubrk_isBoundary(bi, char_pos)) { ret_pos = grapheme_count_graphemes(bi, uhaystack,char_pos); if(puchar_pos) { *puchar_pos = char_pos; } } else { ret_pos = -1; } if (uhaystack) { efree( uhaystack ); } if (uneedle) { efree( uneedle ); } ubrk_close (bi); usearch_close (src); return ret_pos; }
static void php_intl_idn_to(INTERNAL_FUNCTION_PARAMETERS, const zend_string *domain, uint32_t option, int mode) { UChar* ustring = NULL; int ustring_len = 0; UErrorCode status; zend_string *u8str; /* convert the string to UTF-16. */ status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&ustring, &ustring_len, ZSTR_VAL(domain), ZSTR_LEN(domain), &status); if (U_FAILURE(status)) { intl_error_set_code(NULL, status); /* Set error messages. */ intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 ); if (ustring) { efree(ustring); } RETURN_FALSE; } else { UChar converted[MAXPATHLEN]; int32_t converted_ret_len; status = U_ZERO_ERROR; #if U_ICU_VERSION_MAJOR_NUM >= 55 UIDNAInfo info = UIDNA_INFO_INITIALIZER; UIDNA *idna = uidna_openUTS46((int32_t)option, &status); if (U_FAILURE(status)) { intl_error_set( NULL, status, "idn_to_ascii: failed to create an UIDNA instance", 0 ); RETURN_FALSE; } if (mode == INTL_IDN_TO_ASCII) { converted_ret_len = uidna_nameToASCII(idna, ustring, ustring_len, converted, MAXPATHLEN, &info, &status); } else { converted_ret_len = uidna_nameToUnicode(idna, ustring, ustring_len, converted, MAXPATHLEN, &info, &status); } uidna_close(idna); #else UParseError parse_error; if (mode == INTL_IDN_TO_ASCII) { converted_ret_len = uidna_IDNToASCII(ustring, ustring_len, converted, MAXPATHLEN, (int32_t)option, &parse_error, &status); } else { converted_ret_len = uidna_IDNToUnicode(ustring, ustring_len, converted, MAXPATHLEN, (int32_t)option, &parse_error, &status); } #endif efree(ustring); if (U_FAILURE(status)) { intl_error_set( NULL, status, "idn_to_ascii: cannot convert to ASCII", 0 ); RETURN_FALSE; } status = U_ZERO_ERROR; u8str = intl_convert_utf16_to_utf8(converted, converted_ret_len, &status); if (!u8str) { /* Set global error code. */ intl_error_set_code(NULL, status); /* Set error messages. */ intl_error_set_custom_msg( NULL, "Error converting output string to UTF-8", 0 ); RETURN_FALSE; } } /* return the allocated string, not a duplicate */ RETVAL_NEW_STR(u8str); }
static int create_transliterator( char *str_id, int str_id_len, zend_long direction, zval *object ) { Transliterator_object *to; UChar *ustr_id = NULL; int32_t ustr_id_len = 0; UTransliterator *utrans; UParseError parse_error = {0, -1}; intl_error_reset( NULL ); if( ( direction != TRANSLITERATOR_FORWARD ) && (direction != TRANSLITERATOR_REVERSE ) ) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "transliterator_create: invalid direction", 0 ); return FAILURE; } object_init_ex( object, Transliterator_ce_ptr ); TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK; /* fetch zend object from zval "object" into "to" */ /* Convert transliterator id to UTF-16 */ intl_convert_utf8_to_utf16( &ustr_id, &ustr_id_len, str_id, str_id_len, TRANSLITERATOR_ERROR_CODE_P( to ) ); if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) { intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) ); intl_error_set_custom_msg( NULL, "String conversion of id to UTF-16 failed", 0 ); zval_dtor( object ); return FAILURE; } /* Open ICU Transliterator. */ utrans = utrans_openU( ustr_id, ustr_id_len, (UTransDirection ) direction, NULL, -1, &parse_error, TRANSLITERATOR_ERROR_CODE_P( to ) ); if (ustr_id) { efree( ustr_id ); } if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) { char *buf = NULL; intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) ); spprintf( &buf, 0, "transliterator_create: unable to open ICU transliterator" " with id \"%s\"", str_id ); if( buf == NULL ) { intl_error_set_custom_msg( NULL, "transliterator_create: unable to open ICU transliterator", 0 ); } else { intl_error_set_custom_msg( NULL, buf, /* copy message */ 1 ); efree( buf ); } zval_dtor( object ); return FAILURE; } transliterator_object_construct( object, utrans, TRANSLITERATOR_ERROR_CODE_P( to ) ); /* no need to close the transliterator manually on construction error */ if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) { intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) ); intl_error_set_custom_msg( NULL, "transliterator_create: internal constructor call failed", 0 ); zval_dtor( object ); return FAILURE; } return SUCCESS; }
static void php_intl_idn_to(INTERNAL_FUNCTION_PARAMETERS, int mode) { unsigned char* domain; int domain_len; long option = 0; UChar* ustring = NULL; int ustring_len = 0; UErrorCode status; char *converted_utf8; int32_t converted_utf8_len; UChar converted[MAXPATHLEN]; int32_t converted_ret_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", (char **)&domain, &domain_len, &option) == FAILURE) { return; } if (domain_len < 1) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "idn_to_ascii: empty domain name", 0 TSRMLS_CC ); RETURN_FALSE; } /* convert the string to UTF-16. */ status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&ustring, &ustring_len, (char*) domain, domain_len, &status ); if (U_FAILURE(status)) { intl_error_set_code(NULL, status TSRMLS_CC); /* Set error messages. */ intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 TSRMLS_CC ); efree(ustring); RETURN_FALSE; } else { UParseError parse_error; status = U_ZERO_ERROR; if (mode == INTL_IDN_TO_ASCII) { converted_ret_len = uidna_IDNToASCII(ustring, ustring_len, converted, MAXPATHLEN, (int32_t)option, &parse_error, &status); } else { converted_ret_len = uidna_IDNToUnicode(ustring, ustring_len, converted, MAXPATHLEN, (int32_t)option, &parse_error, &status); } efree(ustring); if (U_FAILURE(status)) { intl_error_set( NULL, status, "idn_to_ascii: cannot convert to ASCII", 0 TSRMLS_CC ); RETURN_FALSE; } status = U_ZERO_ERROR; intl_convert_utf16_to_utf8(&converted_utf8, &converted_utf8_len, converted, converted_ret_len, &status); if (U_FAILURE(status)) { /* Set global error code. */ intl_error_set_code(NULL, status TSRMLS_CC); /* Set error messages. */ intl_error_set_custom_msg( NULL, "Error converting output string to UTF-8", 0 TSRMLS_CC ); efree(converted_utf8); RETURN_FALSE; } } /* return the allocated string, not a duplicate */ RETURN_STRINGL(((char *)converted_utf8), converted_utf8_len, 0); }
static void regexp_ctor(INTERNAL_FUNCTION_PARAMETERS) { zval *object; Regexp_object *ro; char *pattern; int32_t pattern_len; UChar *upattern = NULL; int32_t upattern_len = 0; zval *zflags = NULL; uint32_t flags = 0; UParseError pe = { -1, -1, {0}, {0} }; intl_error_reset(NULL TSRMLS_CC); object = return_value; if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &pattern, &pattern_len, &zflags)) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "bad arguments", 0 TSRMLS_CC); zval_dtor(object); RETURN_NULL(); } if (NULL != zflags) { switch (Z_TYPE_P(zflags)) { case IS_LONG: flags = (uint32_t) Z_LVAL_P(zflags); break; case IS_STRING: { const char *p; for (p = Z_STRVAL_P(zflags); '\0' != *p; p++) { switch (*p) { case 'i': flags |= UREGEX_CASE_INSENSITIVE; break; case 'm': flags |= UREGEX_MULTILINE; break; case 's': flags |= UREGEX_DOTALL; break; case 'x': flags |= UREGEX_COMMENTS; break; case 'w': flags |= UREGEX_UWORD; break; default: intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "invalid modifier", 0 TSRMLS_CC); zval_dtor(object); RETURN_NULL(); } } break; } default: intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "bad arguments", 0 TSRMLS_CC); zval_dtor(object); RETURN_NULL(); } } ro = (Regexp_object *) zend_object_store_get_object(object TSRMLS_CC); intl_convert_utf8_to_utf16(&upattern, &upattern_len, pattern, pattern_len, REGEXP_ERROR_CODE_P(ro)); INTL_CTOR_CHECK_STATUS(ro, "string conversion of pattern to UTF-16 failed"); ro->uregex = uregex_open(upattern, upattern_len, flags, &pe, REGEXP_ERROR_CODE_P(ro)); efree(upattern); if (U_FAILURE(REGEXP_ERROR_CODE(ro))) { intl_error_set_code(NULL, REGEXP_ERROR_CODE(ro) TSRMLS_CC); if (-1 != pe.line) { regexp_parse_error_to_string(pe, pattern, pattern_len); } else { intl_error_set_custom_msg(NULL, "unable to compile ICU regular expression", 0 TSRMLS_CC); } zval_dtor(object); RETURN_NULL(); } }
/* {{{ */ static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) { char* locale; int locale_len = 0; zval* object; long date_type = 0; long time_type = 0; long calendar = UCAL_GREGORIAN; char* timezone_str = NULL; int timezone_str_len = 0; char* pattern_str = NULL; int pattern_str_len = 0; UChar* svalue = NULL; /* UTF-16 pattern_str */ int slength = 0; UChar* timezone_utf16 = NULL; /* UTF-16 timezone_str */ int timezone_utf16_len = 0; UCalendar ucal_obj = NULL; IntlDateFormatter_object* dfo; intl_error_reset( NULL TSRMLS_CC ); object = return_value; /* Parse parameters. */ if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "sll|sls", &locale, &locale_len, &date_type, &time_type, &timezone_str, &timezone_str_len, &calendar,&pattern_str, &pattern_str_len ) == FAILURE ) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: unable to parse input parameters", 0 TSRMLS_CC ); zval_dtor(return_value); RETURN_NULL(); } INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value); if (calendar != UCAL_TRADITIONAL && calendar != UCAL_GREGORIAN) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: " "invalid value for calendar type; it must be one of " "IntlDateFormatter::TRADITIONAL (locale's default calendar) " "or IntlDateFormatter::GREGORIAN", 0 TSRMLS_CC); goto error; } DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK; if (DATE_FORMAT_OBJECT(dfo) != NULL) { intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: cannot call constructor twice", 0 TSRMLS_CC); return; } /* Convert pattern (if specified) to UTF-16. */ if( pattern_str && pattern_str_len>0 ){ intl_convert_utf8_to_utf16(&svalue, &slength, pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo)); if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { /* object construction -> only set global error */ intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: " "error converting pattern to UTF-16", 0 TSRMLS_CC); goto error; } } /* resources allocated from now on */ /* Convert pattern (if specified) to UTF-16. */ if( timezone_str && timezone_str_len >0 ){ intl_convert_utf8_to_utf16(&timezone_utf16, &timezone_utf16_len, timezone_str, timezone_str_len, &INTL_DATA_ERROR_CODE(dfo)); if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: " "error converting timezone_str to UTF-16", 0 TSRMLS_CC); goto error; } } if(locale_len == 0) { locale = INTL_G(default_locale); } if( pattern_str && pattern_str_len>0 ){ DATE_FORMAT_OBJECT(dfo) = udat_open(UDAT_IGNORE, UDAT_IGNORE, locale, timezone_utf16, timezone_utf16_len, svalue, slength, &INTL_DATA_ERROR_CODE(dfo)); } else { DATE_FORMAT_OBJECT(dfo) = udat_open(time_type, date_type, locale, timezone_utf16, timezone_utf16_len, svalue, slength, &INTL_DATA_ERROR_CODE(dfo)); } if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { if (calendar != UCAL_TRADITIONAL) { ucal_obj = ucal_open(timezone_utf16, timezone_utf16_len, locale, calendar, &INTL_DATA_ERROR_CODE(dfo)); if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { udat_setCalendar(DATE_FORMAT_OBJECT(dfo), ucal_obj); ucal_close(ucal_obj); } else { intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create" ": error opening calendar", 0 TSRMLS_CC); goto error; } } } else { intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date " "formatter creation failed", 0 TSRMLS_CC); goto error; } /* Set the class variables */ dfo->date_type = date_type; dfo->time_type = time_type; dfo->calendar = calendar; if( timezone_str && timezone_str_len > 0){ dfo->timezone_id = estrndup( timezone_str, timezone_str_len); } error: if (svalue) { efree(svalue); } if (timezone_utf16) { efree(timezone_utf16); } if (U_FAILURE(intl_error_get_code(NULL TSRMLS_CC))) { /* free_object handles partially constructed instances fine */ zval_dtor(return_value); RETVAL_NULL(); } }