@@ -52,7 +52,44 @@ PHONGO_API zend_class_entry *php_phongo_utcdatetime_ce;
5252
5353zend_object_handlers php_phongo_handler_utcdatetime ;
5454
55- static void php_phongo_utcdatetime_init_from_current_time (php_phongo_utcdatetime_t * intern )
55+ /* Initialize the object from an integer and return whether it was successful. */
56+ static bool php_phongo_utcdatetime_init (php_phongo_utcdatetime_t * intern , int64_t milliseconds )
57+ {
58+ intern -> milliseconds = milliseconds ;
59+ intern -> initialized = true;
60+
61+ return true;
62+ }
63+
64+ /* Initialize the object from a HashTable and return whether it was successful. */
65+ static bool php_phongo_utcdatetime_init_from_hash (php_phongo_utcdatetime_t * intern , HashTable * props )
66+ {
67+ #if PHP_VERSION_ID >= 70000
68+ zval * milliseconds ;
69+
70+ if ((milliseconds = zend_hash_str_find (props , "milliseconds" , sizeof ("milliseconds" )- 1 )) && Z_TYPE_P (milliseconds ) == IS_LONG ) {
71+ return php_phongo_utcdatetime_init (intern , Z_LVAL_P (milliseconds ));
72+ }
73+
74+ if ((milliseconds = zend_hash_str_find (props , "milliseconds" , sizeof ("milliseconds" )- 1 )) && Z_TYPE_P (milliseconds ) == IS_STRING ) {
75+ return php_phongo_utcdatetime_init (intern , STRTOLL (Z_STRVAL_P (milliseconds )));
76+ }
77+ #else
78+ zval * * milliseconds ;
79+
80+ if (zend_hash_find (props , "milliseconds" , sizeof ("milliseconds" ), (void * * ) & milliseconds ) == SUCCESS && Z_TYPE_PP (milliseconds ) == IS_LONG ) {
81+ return php_phongo_utcdatetime_init (intern , Z_LVAL_PP (milliseconds ));
82+ }
83+
84+ if (zend_hash_find (props , "milliseconds" , sizeof ("milliseconds" ), (void * * ) & milliseconds ) == SUCCESS && Z_TYPE_PP (milliseconds ) == IS_STRING ) {
85+ return php_phongo_utcdatetime_init (intern , STRTOLL (Z_STRVAL_PP (milliseconds )));
86+ }
87+ #endif
88+ return false;
89+ }
90+
91+ /* Initialize the object from the current time and return whether it was successful. */
92+ static bool php_phongo_utcdatetime_init_from_current_time (php_phongo_utcdatetime_t * intern )
5693{
5794 int64_t sec , usec ;
5895 struct timeval cur_time ;
@@ -62,9 +99,13 @@ static void php_phongo_utcdatetime_init_from_current_time(php_phongo_utcdatetime
6299 usec = cur_time .tv_usec ;
63100
64101 intern -> milliseconds = (sec * 1000 ) + (usec / 1000 );
102+ intern -> initialized = true;
103+
104+ return true;
65105}
66106
67- static void php_phongo_utcdatetime_init_from_date (php_phongo_utcdatetime_t * intern , php_date_obj * datetime_obj )
107+ /* Initialize the object from a DateTime object and return whether it was successful. */
108+ static bool php_phongo_utcdatetime_init_from_date (php_phongo_utcdatetime_t * intern , php_date_obj * datetime_obj )
68109{
69110 int64_t sec , usec ;
70111
@@ -73,6 +114,9 @@ static void php_phongo_utcdatetime_init_from_date(php_phongo_utcdatetime_t *inte
73114 usec = (int64_t ) floor (datetime_obj -> time -> f * 1000000 + 0.5 );
74115
75116 intern -> milliseconds = (sec * 1000 ) + (usec / 1000 );
117+ intern -> initialized = true;
118+
119+ return true;
76120}
77121
78122/* {{{ proto BSON\UTCDateTime UTCDateTime::__construct([integer|DateTimeInterface $milliseconds = null])
@@ -115,7 +159,7 @@ PHP_METHOD(UTCDateTime, __construct)
115159 return ;
116160 }
117161
118- intern -> milliseconds = milliseconds ;
162+ php_phongo_utcdatetime_init ( intern , milliseconds ) ;
119163 }
120164#elif SIZEOF_PHONGO_LONG == 4
121165 {
@@ -127,7 +171,7 @@ PHP_METHOD(UTCDateTime, __construct)
127171 return ;
128172 }
129173
130- intern -> milliseconds = STRTOLL (s_milliseconds );
174+ php_phongo_utcdatetime_init ( intern , STRTOLL (s_milliseconds ) );
131175 }
132176#else
133177# error Unsupported architecture (integers are neither 32-bit nor 64-bit)
@@ -137,6 +181,30 @@ PHP_METHOD(UTCDateTime, __construct)
137181
138182}
139183/* }}} */
184+
185+ /* {{{ proto UTCDateTime::__set_state(array $properties)
186+ */
187+ PHP_METHOD (UTCDateTime , __set_state )
188+ {
189+ php_phongo_utcdatetime_t * intern ;
190+ HashTable * props ;
191+ zval * array ;
192+
193+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "a" , & array ) == FAILURE ) {
194+ RETURN_FALSE ;
195+ }
196+
197+ object_init_ex (return_value , php_phongo_utcdatetime_ce );
198+
199+ intern = Z_UTCDATETIME_OBJ_P (return_value );
200+ props = Z_ARRVAL_P (array );
201+
202+ if (!php_phongo_utcdatetime_init_from_hash (intern , props )) {
203+ php_error (E_ERROR , "Invalid serialization data for UTCDateTime object" );
204+ }
205+ }
206+ /* }}} */
207+
140208/* {{{ proto string UTCDateTime::__toString()
141209 Returns the string representation of the UTCDateTime */
142210PHP_METHOD (UTCDateTime , __toString )
@@ -157,6 +225,27 @@ PHP_METHOD(UTCDateTime, __toString)
157225 efree (tmp );
158226}
159227/* }}} */
228+
229+ /* {{{ proto UTCDateTime::__wakeup()
230+ */
231+ PHP_METHOD (UTCDateTime , __wakeup )
232+ {
233+ php_phongo_utcdatetime_t * intern ;
234+ HashTable * props ;
235+
236+ if (zend_parse_parameters_none () == FAILURE ) {
237+ return ;
238+ }
239+
240+ intern = Z_UTCDATETIME_OBJ_P (getThis ());
241+ props = zend_std_get_properties (getThis () TSRMLS_CC );
242+
243+ if (!php_phongo_utcdatetime_init_from_hash (intern , props )) {
244+ php_error (E_ERROR , "Invalid serialization data for UTCDateTime object" );
245+ }
246+ }
247+ /* }}} */
248+
160249/* {{{ proto string UTCDateTime::toDateTime()
161250 Returns DateTime object representing this UTCDateTime */
162251PHP_METHOD (UTCDateTime , toDateTime )
@@ -191,18 +280,20 @@ ZEND_BEGIN_ARG_INFO_EX(ai_UTCDateTime___construct, 0, 0, 1)
191280 ZEND_ARG_INFO (0 , milliseconds )
192281ZEND_END_ARG_INFO ();
193282
194- ZEND_BEGIN_ARG_INFO_EX (ai_UTCDateTime___toString , 0 , 0 , 0 )
195- ZEND_END_ARG_INFO ();
283+ ZEND_BEGIN_ARG_INFO_EX (ai_UTCDateTime___set_state , 0 , 0 , 1 )
284+ ZEND_ARG_ARRAY_INFO (0 , properties , 0 )
285+ ZEND_END_ARG_INFO ()
196286
197- ZEND_BEGIN_ARG_INFO_EX (ai_UTCDateTime_toDateTime , 0 , 0 , 0 )
198- ZEND_END_ARG_INFO ();
287+ ZEND_BEGIN_ARG_INFO_EX (ai_UTCDateTime_void , 0 , 0 , 0 )
288+ ZEND_END_ARG_INFO ()
199289
200290
201291static zend_function_entry php_phongo_utcdatetime_me [] = {
202292 PHP_ME (UTCDateTime , __construct , ai_UTCDateTime___construct , ZEND_ACC_PUBLIC |ZEND_ACC_FINAL )
203- PHP_ME (UTCDateTime , __toString , ai_UTCDateTime___toString , ZEND_ACC_PUBLIC |ZEND_ACC_FINAL )
204- PHP_ME (UTCDateTime , toDateTime , ai_UTCDateTime_toDateTime , ZEND_ACC_PUBLIC |ZEND_ACC_FINAL )
205- PHP_ME (Manager , __wakeUp , NULL , ZEND_ACC_PUBLIC )
293+ PHP_ME (UTCDateTime , __set_state , ai_UTCDateTime___set_state , ZEND_ACC_PUBLIC |ZEND_ACC_STATIC )
294+ PHP_ME (UTCDateTime , __toString , ai_UTCDateTime_void , ZEND_ACC_PUBLIC |ZEND_ACC_FINAL )
295+ PHP_ME (UTCDateTime , __wakeup , ai_UTCDateTime_void , ZEND_ACC_PUBLIC )
296+ PHP_ME (UTCDateTime , toDateTime , ai_UTCDateTime_void , ZEND_ACC_PUBLIC |ZEND_ACC_FINAL )
206297 PHP_FE_END
207298};
208299
@@ -245,33 +336,53 @@ phongo_create_object_retval php_phongo_utcdatetime_create_object(zend_class_entr
245336#endif
246337} /* }}} */
247338
248- HashTable * php_phongo_utcdatetime_get_debug_info (zval * object , int * is_temp TSRMLS_DC ) /* {{{ */
339+ HashTable * php_phongo_utcdatetime_get_properties (zval * object TSRMLS_DC ) /* {{{ */
249340{
250341 php_phongo_utcdatetime_t * intern ;
251- #if PHP_VERSION_ID >= 70000
252- zval retval ;
253- #else
254- zval retval = zval_used_for_init ;
255- #endif
342+ HashTable * props ;
256343
257- * is_temp = 1 ;
258- intern = Z_UTCDATETIME_OBJ_P (object );
344+ intern = Z_UTCDATETIME_OBJ_P ( object ) ;
345+ props = zend_std_get_properties (object TSRMLS_CC );
259346
260- array_init (& retval );
347+ if (!intern -> initialized ) {
348+ return props ;
349+ }
261350
262351#if SIZEOF_LONG == 4
263352 {
264- char tmp [24 ];
265- int tmp_len ;
353+ char s_milliseconds [24 ];
354+ int s_milliseconds_len ;
266355
267- tmp_len = snprintf (tmp , sizeof (tmp ), "%" PRId64 , intern -> milliseconds );
268- ADD_ASSOC_STRINGL (& retval , "milliseconds" , tmp , tmp_len );
356+ s_milliseconds_len = snprintf (s_milliseconds , sizeof (s_milliseconds ), "%" PRId64 , intern -> milliseconds );
269357 }
358+ #endif
359+
360+ #if PHP_VERSION_ID >= 70000
361+ {
362+ zval milliseconds ;
363+
364+ #if SIZEOF_LONG == 4
365+ ZVAL_STRINGL (& milliseconds , s_milliseconds , s_milliseconds_len );
270366#else
271- ADD_ASSOC_LONG_EX (& retval , "milliseconds" , intern -> milliseconds );
367+ ZVAL_LONG (& milliseconds , intern -> milliseconds );
368+ #endif
369+ zend_hash_str_update (props , "milliseconds" , sizeof ("milliseconds" )- 1 , & milliseconds );
370+ }
371+ #else
372+ {
373+ zval * milliseconds ;
374+
375+ MAKE_STD_ZVAL (milliseconds );
376+ #if SIZEOF_LONG == 4
377+ ZVAL_STRINGL (milliseconds , s_milliseconds , s_milliseconds_len , 1 );
378+ #else
379+ ZVAL_LONG (milliseconds , intern -> milliseconds );
380+ #endif
381+ zend_hash_update (props , "milliseconds" , sizeof ("milliseconds" ), & milliseconds , sizeof (milliseconds ), NULL );
382+ }
272383#endif
273384
274- return Z_ARRVAL ( retval ) ;
385+ return props ;
275386} /* }}} */
276387/* }}} */
277388
@@ -285,11 +396,10 @@ PHP_MINIT_FUNCTION(UTCDateTime)
285396 php_phongo_utcdatetime_ce = zend_register_internal_class (& ce TSRMLS_CC );
286397 php_phongo_utcdatetime_ce -> create_object = php_phongo_utcdatetime_create_object ;
287398 PHONGO_CE_FINAL (php_phongo_utcdatetime_ce );
288- PHONGO_CE_DISABLE_SERIALIZATION (php_phongo_utcdatetime_ce );
289399
290400 zend_class_implements (php_phongo_utcdatetime_ce TSRMLS_CC , 1 , php_phongo_type_ce );
291401 memcpy (& php_phongo_handler_utcdatetime , phongo_get_std_object_handlers (), sizeof (zend_object_handlers ));
292- php_phongo_handler_utcdatetime .get_debug_info = php_phongo_utcdatetime_get_debug_info ;
402+ php_phongo_handler_utcdatetime .get_properties = php_phongo_utcdatetime_get_properties ;
293403#if PHP_VERSION_ID >= 70000
294404 php_phongo_handler_utcdatetime .free_obj = php_phongo_utcdatetime_free_object ;
295405 php_phongo_handler_utcdatetime .offset = XtOffsetOf (php_phongo_utcdatetime_t , std );
0 commit comments