dateformat_create.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | http://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Authors: Kirti Velankar <kirtig@yahoo-inc.com> |
  14. | Gustavo Lopes <cataphract@php.net> |
  15. +----------------------------------------------------------------------+
  16. */
  17. #include "../intl_cppshims.h"
  18. #include <unicode/timezone.h>
  19. #include <unicode/calendar.h>
  20. #include <unicode/datefmt.h>
  21. extern "C" {
  22. #include <unicode/ustring.h>
  23. #include <unicode/udat.h>
  24. #include "php_intl.h"
  25. #include "dateformat_create.h"
  26. #include "dateformat_class.h"
  27. #define USE_TIMEZONE_POINTER 1
  28. #include "../timezone/timezone_class.h"
  29. #include "../intl_convert.h"
  30. }
  31. #include "dateformat_helpers.h"
  32. /* {{{ */
  33. static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
  34. {
  35. zval *object;
  36. const char *locale_str;
  37. int locale_len = 0;
  38. Locale locale;
  39. long date_type = 0;
  40. long time_type = 0;
  41. zval *calendar_zv = NULL;
  42. Calendar *calendar = NULL;
  43. long calendar_type;
  44. bool calendar_owned;
  45. zval **timezone_zv = NULL;
  46. TimeZone *timezone = NULL;
  47. bool explicit_tz;
  48. char* pattern_str = NULL;
  49. int pattern_str_len = 0;
  50. UChar* svalue = NULL; /* UTF-16 pattern_str */
  51. int slength = 0;
  52. IntlDateFormatter_object* dfo;
  53. intl_error_reset(NULL TSRMLS_CC);
  54. object = return_value;
  55. /* Parse parameters. */
  56. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll|Zzs",
  57. &locale_str, &locale_len, &date_type, &time_type, &timezone_zv,
  58. &calendar_zv, &pattern_str, &pattern_str_len) == FAILURE) {
  59. intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: "
  60. "unable to parse input parameters", 0 TSRMLS_CC);
  61. zval_dtor(return_value);
  62. RETURN_NULL();
  63. }
  64. INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
  65. if (locale_len == 0) {
  66. locale_str = intl_locale_get_default(TSRMLS_C);
  67. }
  68. locale = Locale::createFromName(locale_str);
  69. DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK;
  70. if (DATE_FORMAT_OBJECT(dfo) != NULL) {
  71. intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR,
  72. "datefmt_create: cannot call constructor twice", 0 TSRMLS_CC);
  73. return;
  74. }
  75. /* process calendar */
  76. if (datefmt_process_calendar_arg(calendar_zv, locale, "datefmt_create",
  77. INTL_DATA_ERROR_P(dfo), calendar, calendar_type,
  78. calendar_owned TSRMLS_CC)
  79. == FAILURE) {
  80. goto error;
  81. }
  82. /* process timezone */
  83. explicit_tz = timezone_zv != NULL && Z_TYPE_PP(timezone_zv) != IS_NULL;
  84. if (explicit_tz || calendar_owned ) {
  85. //we have an explicit time zone or a non-object calendar
  86. timezone = timezone_process_timezone_argument(timezone_zv,
  87. INTL_DATA_ERROR_P(dfo), "datefmt_create" TSRMLS_CC);
  88. if (timezone == NULL) {
  89. goto error;
  90. }
  91. }
  92. /* Convert pattern (if specified) to UTF-16. */
  93. if (pattern_str && pattern_str_len > 0) {
  94. intl_convert_utf8_to_utf16(&svalue, &slength,
  95. pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo));
  96. if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
  97. /* object construction -> only set global error */
  98. intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: "
  99. "error converting pattern to UTF-16", 0 TSRMLS_CC);
  100. goto error;
  101. }
  102. }
  103. if (pattern_str && pattern_str_len > 0) {
  104. DATE_FORMAT_OBJECT(dfo) = udat_open(UDAT_IGNORE, UDAT_IGNORE,
  105. locale_str, NULL, 0, svalue, slength,
  106. &INTL_DATA_ERROR_CODE(dfo));
  107. } else {
  108. DATE_FORMAT_OBJECT(dfo) = udat_open((UDateFormatStyle)time_type,
  109. (UDateFormatStyle)date_type, locale_str, NULL, 0, svalue,
  110. slength, &INTL_DATA_ERROR_CODE(dfo));
  111. }
  112. if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
  113. DateFormat *df = (DateFormat*)DATE_FORMAT_OBJECT(dfo);
  114. if (calendar_owned) {
  115. df->adoptCalendar(calendar);
  116. calendar_owned = false;
  117. } else {
  118. df->setCalendar(*calendar);
  119. }
  120. if (timezone != NULL) {
  121. df->adoptTimeZone(timezone);
  122. }
  123. } else {
  124. intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date "
  125. "formatter creation failed", 0 TSRMLS_CC);
  126. goto error;
  127. }
  128. /* Set the class variables */
  129. dfo->date_type = date_type;
  130. dfo->time_type = time_type;
  131. dfo->calendar = calendar_type;
  132. dfo->requested_locale = estrdup(locale_str);
  133. error:
  134. if (svalue) {
  135. efree(svalue);
  136. }
  137. if (timezone != NULL && DATE_FORMAT_OBJECT(dfo) == NULL) {
  138. delete timezone;
  139. }
  140. if (calendar != NULL && calendar_owned) {
  141. delete calendar;
  142. }
  143. if (U_FAILURE(intl_error_get_code(NULL TSRMLS_CC))) {
  144. /* free_object handles partially constructed instances fine */
  145. zval_dtor(return_value);
  146. RETVAL_NULL();
  147. }
  148. }
  149. /* }}} */
  150. /* {{{ proto IntlDateFormatter IntlDateFormatter::create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern] )
  151. * Create formatter. }}} */
  152. /* {{{ proto IntlDateFormatter datefmt_create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern)
  153. * Create formatter.
  154. */
  155. U_CFUNC PHP_FUNCTION( datefmt_create )
  156. {
  157. object_init_ex( return_value, IntlDateFormatter_ce_ptr );
  158. datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  159. }
  160. /* }}} */
  161. /* {{{ proto void IntlDateFormatter::__construct(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern])
  162. * IntlDateFormatter object constructor.
  163. */
  164. U_CFUNC PHP_METHOD( IntlDateFormatter, __construct )
  165. {
  166. /* return_value param is being changed, therefore we will always return
  167. * NULL here */
  168. return_value = getThis();
  169. datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  170. }
  171. /* }}} */