3131
3232zend_class_entry * phongo_readpreference_ce ;
3333
34+ static const char * phongo_readpreference_get_mode_string (const mongoc_read_prefs_t * read_prefs )
35+ {
36+ switch (mongoc_read_prefs_get_mode (read_prefs )) {
37+ case MONGOC_READ_PRIMARY :
38+ return PHONGO_READ_PRIMARY ;
39+ case MONGOC_READ_PRIMARY_PREFERRED :
40+ return PHONGO_READ_PRIMARY_PREFERRED ;
41+ case MONGOC_READ_SECONDARY :
42+ return PHONGO_READ_SECONDARY ;
43+ case MONGOC_READ_SECONDARY_PREFERRED :
44+ return PHONGO_READ_SECONDARY_PREFERRED ;
45+ case MONGOC_READ_NEAREST :
46+ return PHONGO_READ_NEAREST ;
47+ default :
48+ return "" ;
49+ }
50+ }
51+
52+ static void phongo_readpreference_update_properties (phongo_readpreference_t * intern )
53+ {
54+ const bson_t * bson ;
55+
56+ zend_update_property_string (phongo_readpreference_ce , & intern -> std , ZEND_STRL ("mode" ), phongo_readpreference_get_mode_string (intern -> read_preference ));
57+ zend_update_property_long (phongo_readpreference_ce , & intern -> std , ZEND_STRL ("maxStalenessSeconds" ), mongoc_read_prefs_get_max_staleness_seconds (intern -> read_preference ));
58+
59+ bson = mongoc_read_prefs_get_tags (intern -> read_preference );
60+
61+ if (!bson_empty0 (bson )) {
62+ phongo_bson_state state ;
63+
64+ PHONGO_BSON_INIT_STATE (state );
65+ state .map .root .type = PHONGO_TYPEMAP_NATIVE_ARRAY ;
66+
67+ if (!phongo_bson_to_zval_ex (bson , & state )) {
68+ // Exception already thrown
69+ zval_ptr_dtor (& state .zchild );
70+ return ;
71+ }
72+
73+ zend_update_property (phongo_readpreference_ce , & intern -> std , ZEND_STRL ("tags" ), & state .zchild );
74+ zval_ptr_dtor (& state .zchild );
75+ } else {
76+ zend_update_property_null (phongo_readpreference_ce , & intern -> std , ZEND_STRL ("tags" ));
77+ }
78+
79+ bson = mongoc_read_prefs_get_hedge (intern -> read_preference );
80+
81+ if (!bson_empty0 (bson )) {
82+ phongo_bson_state state ;
83+
84+ PHONGO_BSON_INIT_STATE (state );
85+
86+ if (!phongo_bson_to_zval_ex (bson , & state )) {
87+ // Exception already thrown
88+ zval_ptr_dtor (& state .zchild );
89+ return ;
90+ }
91+
92+ zend_update_property (phongo_readpreference_ce , & intern -> std , ZEND_STRL ("hedge" ), & state .zchild );
93+ zval_ptr_dtor (& state .zchild );
94+ } else {
95+ zend_update_property_null (phongo_readpreference_ce , & intern -> std , ZEND_STRL ("hedge" ));
96+ }
97+ }
98+
3499/* Initialize the object from a HashTable and return whether it was successful.
35100 * An exception will be thrown on error. */
36101static bool phongo_readpreference_init_from_hash (phongo_readpreference_t * intern , HashTable * props )
@@ -83,7 +148,7 @@ static bool phongo_readpreference_init_from_hash(phongo_readpreference_t* intern
83148
84149 mongoc_read_prefs_set_tags (intern -> read_preference , tags );
85150 bson_destroy (tags );
86- } else {
151+ } else if ( Z_TYPE_P ( tagSets ) != IS_NULL ) {
87152 phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT , "%s initialization requires \"tags\" field to be array" , ZSTR_VAL (phongo_readpreference_ce -> name ));
88153 goto failure ;
89154 }
@@ -134,7 +199,7 @@ static bool phongo_readpreference_init_from_hash(phongo_readpreference_t* intern
134199
135200 mongoc_read_prefs_set_hedge (intern -> read_preference , hedge_doc );
136201 bson_destroy (hedge_doc );
137- } else {
202+ } else if ( Z_TYPE_P ( hedge ) != IS_NULL ) {
138203 phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT , "%s initialization requires \"hedge\" field to be an array or object" , ZSTR_VAL (phongo_readpreference_ce -> name ));
139204 goto failure ;
140205 }
@@ -145,6 +210,8 @@ static bool phongo_readpreference_init_from_hash(phongo_readpreference_t* intern
145210 goto failure ;
146211 }
147212
213+ phongo_readpreference_update_properties (intern );
214+
148215 return true;
149216
150217failure :
@@ -153,24 +220,6 @@ static bool phongo_readpreference_init_from_hash(phongo_readpreference_t* intern
153220 return false;
154221}
155222
156- static const char * phongo_readpreference_get_mode_string (const mongoc_read_prefs_t * read_prefs )
157- {
158- switch (mongoc_read_prefs_get_mode (read_prefs )) {
159- case MONGOC_READ_PRIMARY :
160- return PHONGO_READ_PRIMARY ;
161- case MONGOC_READ_PRIMARY_PREFERRED :
162- return PHONGO_READ_PRIMARY_PREFERRED ;
163- case MONGOC_READ_SECONDARY :
164- return PHONGO_READ_SECONDARY ;
165- case MONGOC_READ_SECONDARY_PREFERRED :
166- return PHONGO_READ_SECONDARY_PREFERRED ;
167- case MONGOC_READ_NEAREST :
168- return PHONGO_READ_NEAREST ;
169- default :
170- return "" ;
171- }
172- }
173-
174223/* Constructs a new ReadPreference */
175224static PHP_METHOD (MongoDB_Driver_ReadPreference , __construct )
176225{
@@ -281,6 +330,8 @@ static PHP_METHOD(MongoDB_Driver_ReadPreference, __construct)
281330 phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT , "Read preference is not valid" );
282331 return ;
283332 }
333+
334+ phongo_readpreference_update_properties (intern );
284335}
285336
286337static PHP_METHOD (MongoDB_Driver_ReadPreference , __set_state )
@@ -384,89 +435,34 @@ static PHP_METHOD(MongoDB_Driver_ReadPreference, getTagSets)
384435 }
385436}
386437
387- static HashTable * phongo_readpreference_get_properties_hash ( zend_object * object , bool is_temp )
438+ static PHP_METHOD ( MongoDB_Driver_ReadPreference , bsonSerialize )
388439{
389- phongo_readpreference_t * intern ;
390- HashTable * props ;
391- const bson_t * tags ;
392- const bson_t * hedge ;
393-
394- intern = Z_OBJ_READPREFERENCE (object );
395-
396- PHONGO_GET_PROPERTY_HASH_INIT_PROPS (is_temp , intern , props , 4 );
397-
398- if (!intern -> read_preference ) {
399- return props ;
400- }
440+ PHONGO_PARSE_PARAMETERS_NONE ();
401441
402- tags = mongoc_read_prefs_get_tags (intern -> read_preference );
403- hedge = mongoc_read_prefs_get_hedge (intern -> read_preference );
442+ array_init_size (return_value , 4 );
404443
405444 {
406- zval z_mode ;
407-
408- ZVAL_STRING (& z_mode , phongo_readpreference_get_mode_string (intern -> read_preference ));
409- zend_hash_str_update (props , "mode" , sizeof ("mode" ) - 1 , & z_mode );
410- }
411-
412- if (!bson_empty0 (tags )) {
413- phongo_bson_state state ;
414-
415- /* Use PHONGO_TYPEMAP_NATIVE_ARRAY for the root type since tags is an
416- * array; however, inner documents and arrays can use the default. */
417- PHONGO_BSON_INIT_STATE (state );
418- state .map .root .type = PHONGO_TYPEMAP_NATIVE_ARRAY ;
419-
420- if (!phongo_bson_to_zval_ex (tags , & state )) {
421- zval_ptr_dtor (& state .zchild );
422- goto done ;
423- }
424-
425- zend_hash_str_update (props , "tags" , sizeof ("tags" ) - 1 , & state .zchild );
426- }
427-
428- if (mongoc_read_prefs_get_max_staleness_seconds (intern -> read_preference ) != MONGOC_NO_MAX_STALENESS ) {
429- /* Note: valid values for maxStalesnessSeconds will not exceed the range
430- * of 32-bit signed integers, so conditional encoding is not necessary. */
431- long maxStalenessSeconds = mongoc_read_prefs_get_max_staleness_seconds (intern -> read_preference );
432- zval z_max_ss ;
433-
434- ZVAL_LONG (& z_max_ss , maxStalenessSeconds );
435- zend_hash_str_update (props , "maxStalenessSeconds" , sizeof ("maxStalenessSeconds" ) - 1 , & z_max_ss );
436- }
437-
438- if (!bson_empty0 (hedge )) {
439- phongo_bson_state state ;
440-
441- PHONGO_BSON_INIT_STATE (state );
445+ zend_string * string_key ;
446+ zval * val ;
447+
448+ ZEND_HASH_FOREACH_STR_KEY_VAL_IND (HASH_OF (getThis ()), string_key , val )
449+ {
450+ if (
451+ (Z_TYPE_P (val ) == IS_NULL ) || (!strcmp (ZSTR_VAL (string_key ), "maxStalenessSeconds" ) && Z_TYPE_P (val ) == IS_LONG && Z_LVAL_P (val ) == MONGOC_NO_MAX_STALENESS )) {
452+ continue ;
453+ }
442454
443- if (!phongo_bson_to_zval_ex (hedge , & state )) {
444- zval_ptr_dtor (& state .zchild );
445- goto done ;
455+ // Increase the refcount of our zval, as add_assoc_zval takes ownership, leading to the property value being
456+ // freed once the return value goes out of scope
457+ Z_TRY_ADDREF_P (val );
458+ add_assoc_zval (return_value , ZSTR_VAL (string_key ), val );
446459 }
447-
448- zend_hash_str_update (props , "hedge" , sizeof ("hedge" ) - 1 , & state .zchild );
460+ ZEND_HASH_FOREACH_END ();
449461 }
450462
451- done :
452- return props ;
453- }
454-
455- static PHP_METHOD (MongoDB_Driver_ReadPreference , bsonSerialize )
456- {
457- PHONGO_PARSE_PARAMETERS_NONE ();
458-
459- ZVAL_ARR (return_value , phongo_readpreference_get_properties_hash (Z_OBJ_P (getThis ()), true));
460463 convert_to_object (return_value );
461464}
462465
463- static PHP_METHOD (MongoDB_Driver_ReadPreference , __serialize )
464- {
465- PHONGO_PARSE_PARAMETERS_NONE ();
466-
467- RETURN_ARR (phongo_readpreference_get_properties_hash (Z_OBJ_P (getThis ()), true));
468- }
469-
470466static PHP_METHOD (MongoDB_Driver_ReadPreference , __unserialize )
471467{
472468 zval * data ;
@@ -487,11 +483,6 @@ static void phongo_readpreference_free_object(zend_object* object)
487483
488484 zend_object_std_dtor (& intern -> std );
489485
490- if (intern -> properties ) {
491- zend_hash_destroy (intern -> properties );
492- FREE_HASHTABLE (intern -> properties );
493- }
494-
495486 if (intern -> read_preference ) {
496487 mongoc_read_prefs_destroy (intern -> read_preference );
497488 }
@@ -509,15 +500,13 @@ static zend_object* phongo_readpreference_create_object(zend_class_entry* class_
509500 return & intern -> std ;
510501}
511502
512- static HashTable * phongo_readpreference_get_debug_info (zend_object * object , int * is_temp )
503+ static zval * phongo_readpreference_read_property (zend_object * zobj , zend_string * name , int type , void * * cache_slot , zval * rv )
513504{
514- * is_temp = 1 ;
515- return phongo_readpreference_get_properties_hash ( object , true );
516- }
505+ if (! strcmp ( ZSTR_VAL ( name ), "hedge" )) {
506+ php_error_docref ( NULL , E_DEPRECATED , "Property MongoDB\\Driver\\ReadPreference::hedge is deprecated" );
507+ }
517508
518- static HashTable * phongo_readpreference_get_properties (zend_object * object )
519- {
520- return phongo_readpreference_get_properties_hash (object , false);
509+ return zend_std_read_property (zobj , name , type , cache_slot , rv );
521510}
522511
523512void phongo_readpreference_init_ce (INIT_FUNC_ARGS )
@@ -526,10 +515,9 @@ void phongo_readpreference_init_ce(INIT_FUNC_ARGS)
526515 phongo_readpreference_ce -> create_object = phongo_readpreference_create_object ;
527516
528517 memcpy (& phongo_handler_readpreference , phongo_get_std_object_handlers (), sizeof (zend_object_handlers ));
529- phongo_handler_readpreference .get_debug_info = phongo_readpreference_get_debug_info ;
530- phongo_handler_readpreference .get_properties = phongo_readpreference_get_properties ;
531- phongo_handler_readpreference .free_obj = phongo_readpreference_free_object ;
532- phongo_handler_readpreference .offset = XtOffsetOf (phongo_readpreference_t , std );
518+ phongo_handler_readpreference .read_property = phongo_readpreference_read_property ;
519+ phongo_handler_readpreference .free_obj = phongo_readpreference_free_object ;
520+ phongo_handler_readpreference .offset = XtOffsetOf (phongo_readpreference_t , std );
533521}
534522
535523void phongo_readpreference_init (zval * return_value , const mongoc_read_prefs_t * read_prefs )
@@ -540,6 +528,8 @@ void phongo_readpreference_init(zval* return_value, const mongoc_read_prefs_t* r
540528
541529 intern = Z_READPREFERENCE_OBJ_P (return_value );
542530 intern -> read_preference = mongoc_read_prefs_copy (read_prefs );
531+
532+ phongo_readpreference_update_properties (intern );
543533}
544534
545535const mongoc_read_prefs_t * phongo_read_preference_from_zval (zval * zread_preference )
0 commit comments