|
27 | 27 | /* External libs */
|
28 | 28 | #include <bson.h>
|
29 | 29 | #include <mongoc.h>
|
| 30 | +#include <math.h> |
30 | 31 |
|
31 | 32 | /* PHP Core stuff */
|
32 | 33 | #include <php.h>
|
@@ -77,11 +78,7 @@ static bool php_phongo_utcdatetime_init_from_string(php_phongo_utcdatetime_t *in
|
77 | 78 |
|
78 | 79 | errno = 0;
|
79 | 80 |
|
80 |
| -#if defined(PHP_WIN32) |
81 |
| - milliseconds = _atoi64(s_milliseconds); |
82 |
| -#else |
83 | 81 | milliseconds = bson_ascii_strtoll(s_milliseconds, &endptr, 10);
|
84 |
| -#endif |
85 | 82 |
|
86 | 83 | /* errno will set errno if conversion fails; however, we do not need to
|
87 | 84 | * specify the type of error.
|
@@ -161,49 +158,64 @@ static bool php_phongo_utcdatetime_init_from_date(php_phongo_utcdatetime_t *inte
|
161 | 158 | return true;
|
162 | 159 | }
|
163 | 160 |
|
164 |
| -/* {{{ proto void UTCDateTime::__construct([string|DateTimeInterface $milliseconds = null]) |
| 161 | +/* {{{ proto void UTCDateTime::__construct([int|float|string|DateTimeInterface $milliseconds = null]) |
165 | 162 | Construct a new BSON UTCDateTime type from either the current time,
|
166 |
| - milliseconds since the epoch, or a DateTimeInterface object. */ |
| 163 | + milliseconds since the epoch, or a DateTimeInterface object. Defaults to the |
| 164 | + current time. */ |
167 | 165 | PHP_METHOD(UTCDateTime, __construct)
|
168 | 166 | {
|
169 | 167 | php_phongo_utcdatetime_t *intern;
|
170 | 168 | zend_error_handling error_handling;
|
171 |
| - zval *datetime = NULL; |
| 169 | + zval *milliseconds = NULL; |
172 | 170 |
|
173 | 171 | zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
|
174 | 172 | intern = Z_UTCDATETIME_OBJ_P(getThis());
|
175 | 173 |
|
176 |
| - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "|o!", &datetime) == SUCCESS) { |
177 |
| - if (datetime == NULL) { |
178 |
| - php_phongo_utcdatetime_init_from_current_time(intern); |
179 |
| - } else if (instanceof_function(Z_OBJCE_P(datetime), php_date_get_date_ce() TSRMLS_CC)) { |
180 |
| - php_phongo_utcdatetime_init_from_date(intern, Z_PHPDATE_P(datetime)); |
| 174 | + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!", &milliseconds) == FAILURE) { |
| 175 | + zend_restore_error_handling(&error_handling TSRMLS_CC); |
| 176 | + return; |
| 177 | + } |
| 178 | + zend_restore_error_handling(&error_handling TSRMLS_CC); |
| 179 | + |
| 180 | + if (milliseconds == NULL) { |
| 181 | + php_phongo_utcdatetime_init_from_current_time(intern); |
| 182 | + return; |
| 183 | + } |
| 184 | + |
| 185 | + if (Z_TYPE_P(milliseconds) == IS_OBJECT) { |
| 186 | + if (instanceof_function(Z_OBJCE_P(milliseconds), php_date_get_date_ce() TSRMLS_CC)) { |
| 187 | + php_phongo_utcdatetime_init_from_date(intern, Z_PHPDATE_P(milliseconds)); |
181 | 188 | #if PHP_VERSION_ID >= 50500
|
182 |
| - } else if (instanceof_function(Z_OBJCE_P(datetime), php_date_get_immutable_ce() TSRMLS_CC)) { |
183 |
| - php_phongo_utcdatetime_init_from_date(intern, Z_PHPDATE_P(datetime)); |
| 189 | + } else if (instanceof_function(Z_OBJCE_P(milliseconds), php_date_get_immutable_ce() TSRMLS_CC)) { |
| 190 | + php_phongo_utcdatetime_init_from_date(intern, Z_PHPDATE_P(milliseconds)); |
184 | 191 | #endif
|
185 | 192 | } else {
|
186 |
| - phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected instance of DateTimeInterface, %s given", ZSTR_VAL(Z_OBJCE_P(datetime)->name)); |
| 193 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected instance of DateTimeInterface, %s given", ZSTR_VAL(Z_OBJCE_P(milliseconds)->name)); |
187 | 194 | }
|
| 195 | + return; |
| 196 | + } |
188 | 197 |
|
189 |
| - zend_restore_error_handling(&error_handling TSRMLS_CC); |
| 198 | + if (Z_TYPE_P(milliseconds) == IS_LONG) { |
| 199 | + php_phongo_utcdatetime_init(intern, Z_LVAL_P(milliseconds)); |
190 | 200 | return;
|
191 | 201 | }
|
192 | 202 |
|
193 |
| - { |
194 |
| - char *s_milliseconds; |
195 |
| - phongo_zpp_char_len s_milliseconds_len; |
| 203 | + if (Z_TYPE_P(milliseconds) == IS_DOUBLE) { |
| 204 | + char tmp[24]; |
| 205 | + int tmp_len; |
196 | 206 |
|
197 |
| - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s_milliseconds, &s_milliseconds_len) == FAILURE) { |
198 |
| - zend_restore_error_handling(&error_handling TSRMLS_CC); |
199 |
| - return; |
200 |
| - } |
| 207 | + tmp_len = snprintf(tmp, sizeof(tmp), "%.0f", Z_DVAL_P(milliseconds) > 0 ? floor(Z_DVAL_P(milliseconds)) : ceil(Z_DVAL_P(milliseconds))); |
201 | 208 |
|
202 |
| - php_phongo_utcdatetime_init_from_string(intern, s_milliseconds, s_milliseconds_len TSRMLS_CC); |
| 209 | + php_phongo_utcdatetime_init_from_string(intern, tmp, tmp_len TSRMLS_CC); |
| 210 | + return; |
203 | 211 | }
|
204 | 212 |
|
205 |
| - zend_restore_error_handling(&error_handling TSRMLS_CC); |
| 213 | + if (Z_TYPE_P(milliseconds) != IS_STRING) { |
| 214 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected integer or string, %s given", zend_get_type_by_const(Z_TYPE_P(milliseconds))); |
| 215 | + return; |
| 216 | + } |
206 | 217 |
|
| 218 | + php_phongo_utcdatetime_init_from_string(intern, Z_STRVAL_P(milliseconds), Z_STRLEN_P(milliseconds) TSRMLS_CC); |
207 | 219 | }
|
208 | 220 | /* }}} */
|
209 | 221 |
|
|
0 commit comments