16
16
17
17
#include <php.h>
18
18
#include <Zend/zend_interfaces.h>
19
+ #include <ext/standard/php_var.h>
20
+ #if PHP_VERSION_ID >= 70000
21
+ #include <zend_smart_str.h>
22
+ #else
23
+ #include <ext/standard/php_smart_str.h>
24
+ #endif
19
25
20
26
#ifdef HAVE_CONFIG_H
21
27
#include "config.h"
26
32
27
33
zend_class_entry * php_phongo_cursorid_ce ;
28
34
35
+ /* Initialize the object from a numeric string and return whether it was
36
+ * successful. An exception will be thrown on error. */
37
+ static bool php_phongo_cursorid_init_from_string (php_phongo_cursorid_t * intern , const char * s_id , phongo_zpp_char_len s_id_len TSRMLS_DC ) /* {{{ */
38
+ {
39
+ int64_t id ;
40
+ char * endptr = NULL ;
41
+
42
+ /* bson_ascii_strtoll() sets errno if conversion fails. If conversion
43
+ * succeeds, we still want to ensure that the entire string was parsed. */
44
+ id = bson_ascii_strtoll (s_id , & endptr , 10 );
45
+
46
+ if (errno || (endptr && endptr != ((const char * ) s_id + s_id_len ))) {
47
+ phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC , "Error parsing \"%s\" as 64-bit id for %s initialization" , s_id , ZSTR_VAL (php_phongo_cursorid_ce -> name ));
48
+ return false;
49
+ }
50
+
51
+ intern -> id = id ;
52
+ return true;
53
+ } /* }}} */
54
+
55
+ /* Initialize the object from a HashTable and return whether it was successful.
56
+ * An exception will be thrown on error. */
57
+ static bool php_phongo_cursorid_init_from_hash (php_phongo_cursorid_t * intern , HashTable * props TSRMLS_DC ) /* {{{ */
58
+ {
59
+ #if PHP_VERSION_ID >= 70000
60
+ zval * value ;
61
+
62
+ if ((value = zend_hash_str_find (props , "id" , sizeof ("id" ) - 1 )) && Z_TYPE_P (value ) == IS_STRING ) {
63
+ return php_phongo_cursorid_init_from_string (intern , Z_STRVAL_P (value ), Z_STRLEN_P (value ) TSRMLS_CC );
64
+ }
65
+ #else
66
+ zval * * value ;
67
+
68
+ if (zend_hash_find (props , "id" , sizeof ("id" ), (void * * ) & value ) == SUCCESS && Z_TYPE_PP (value ) == IS_STRING ) {
69
+ return php_phongo_cursorid_init_from_string (intern , Z_STRVAL_PP (value ), Z_STRLEN_PP (value ) TSRMLS_CC );
70
+ }
71
+ #endif
72
+
73
+ phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC , "%s initialization requires \"id\" string field" , ZSTR_VAL (php_phongo_cursorid_ce -> name ));
74
+ return false;
75
+ } /* }}} */
76
+
29
77
/* {{{ proto string MongoDB\Driver\CursorId::__toString()
30
78
Returns the string representation of the CursorId */
31
79
static PHP_METHOD (CursorId , __toString )
@@ -45,13 +93,104 @@ static PHP_METHOD(CursorId, __toString)
45
93
efree (tmp );
46
94
} /* }}} */
47
95
96
+ /* {{{ proto string MongoDB\Driver\CursorId::serialize()
97
+ */
98
+ static PHP_METHOD (CursorId , serialize )
99
+ {
100
+ php_phongo_cursorid_t * intern ;
101
+ ZVAL_RETVAL_TYPE retval ;
102
+ php_serialize_data_t var_hash ;
103
+ smart_str buf = { 0 };
104
+ char s_id [24 ];
105
+ int s_id_len ;
106
+
107
+ if (zend_parse_parameters_none () == FAILURE ) {
108
+ return ;
109
+ }
110
+
111
+ intern = Z_CURSORID_OBJ_P (getThis ());
112
+
113
+ s_id_len = snprintf (s_id , sizeof (s_id ), "%" PRId64 , intern -> id );
114
+
115
+ #if PHP_VERSION_ID >= 70000
116
+ array_init_size (& retval , 1 );
117
+ ADD_ASSOC_STRINGL (& retval , "id" , s_id , s_id_len );
118
+ #else
119
+ ALLOC_INIT_ZVAL (retval );
120
+ array_init_size (retval , 1 );
121
+ ADD_ASSOC_STRINGL (retval , "id" , s_id , s_id_len );
122
+ #endif
123
+
124
+ PHP_VAR_SERIALIZE_INIT (var_hash );
125
+ php_var_serialize (& buf , & retval , & var_hash TSRMLS_CC );
126
+ smart_str_0 (& buf );
127
+ PHP_VAR_SERIALIZE_DESTROY (var_hash );
128
+
129
+ PHONGO_RETVAL_SMART_STR (buf );
130
+
131
+ smart_str_free (& buf );
132
+ zval_ptr_dtor (& retval );
133
+ } /* }}} */
134
+
135
+ /* {{{ proto void MongoDB\Driver\CursorId::unserialize(string $serialized)
136
+ */
137
+ static PHP_METHOD (CursorId , unserialize )
138
+ {
139
+ php_phongo_cursorid_t * intern ;
140
+ zend_error_handling error_handling ;
141
+ char * serialized ;
142
+ phongo_zpp_char_len serialized_len ;
143
+ #if PHP_VERSION_ID >= 70000
144
+ zval props ;
145
+ #else
146
+ zval * props ;
147
+ #endif
148
+ php_unserialize_data_t var_hash ;
149
+
150
+ intern = Z_CURSORID_OBJ_P (getThis ());
151
+
152
+ zend_replace_error_handling (EH_THROW , phongo_exception_from_phongo_domain (PHONGO_ERROR_INVALID_ARGUMENT ), & error_handling TSRMLS_CC );
153
+
154
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "s" , & serialized , & serialized_len ) == FAILURE ) {
155
+ zend_restore_error_handling (& error_handling TSRMLS_CC );
156
+ return ;
157
+ }
158
+ zend_restore_error_handling (& error_handling TSRMLS_CC );
159
+
160
+ #if PHP_VERSION_ID < 70000
161
+ ALLOC_INIT_ZVAL (props );
162
+ #endif
163
+ PHP_VAR_UNSERIALIZE_INIT (var_hash );
164
+ if (!php_var_unserialize (& props , (const unsigned char * * ) & serialized , (unsigned char * ) serialized + serialized_len , & var_hash TSRMLS_CC )) {
165
+ zval_ptr_dtor (& props );
166
+ phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "%s unserialization failed" , ZSTR_VAL (php_phongo_cursorid_ce -> name ));
167
+
168
+ PHP_VAR_UNSERIALIZE_DESTROY (var_hash );
169
+ return ;
170
+ }
171
+ PHP_VAR_UNSERIALIZE_DESTROY (var_hash );
172
+
173
+ #if PHP_VERSION_ID >= 70000
174
+ php_phongo_cursorid_init_from_hash (intern , HASH_OF (& props ) TSRMLS_CC );
175
+ #else
176
+ php_phongo_cursorid_init_from_hash (intern , HASH_OF (props ) TSRMLS_CC );
177
+ #endif
178
+ zval_ptr_dtor (& props );
179
+ } /* }}} */
180
+
48
181
/* {{{ MongoDB\Driver\CursorId function entries */
182
+ ZEND_BEGIN_ARG_INFO_EX (ai_CursorId_unserialize , 0 , 0 , 1 )
183
+ ZEND_ARG_INFO (0 , serialized )
184
+ ZEND_END_ARG_INFO ()
185
+
49
186
ZEND_BEGIN_ARG_INFO_EX (ai_CursorId_void , 0 , 0 , 0 )
50
187
ZEND_END_ARG_INFO ()
51
188
52
189
static zend_function_entry php_phongo_cursorid_me [] = {
53
190
/* clang-format off */
54
191
PHP_ME (CursorId , __toString , ai_CursorId_void , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
192
+ PHP_ME (CursorId , serialize , ai_CursorId_void , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
193
+ PHP_ME (CursorId , unserialize , ai_CursorId_unserialize , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
55
194
ZEND_NAMED_ME (__construct , PHP_FN (MongoDB_disabled___construct ), ai_CursorId_void , ZEND_ACC_PRIVATE | ZEND_ACC_FINAL )
56
195
ZEND_NAMED_ME (__wakeup , PHP_FN (MongoDB_disabled___wakeup ), ai_CursorId_void , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
57
196
PHP_FE_END
@@ -131,7 +270,8 @@ void php_phongo_cursorid_init_ce(INIT_FUNC_ARGS) /* {{{ */
131
270
php_phongo_cursorid_ce = zend_register_internal_class (& ce TSRMLS_CC );
132
271
php_phongo_cursorid_ce -> create_object = php_phongo_cursorid_create_object ;
133
272
PHONGO_CE_FINAL (php_phongo_cursorid_ce );
134
- PHONGO_CE_DISABLE_SERIALIZATION (php_phongo_cursorid_ce );
273
+
274
+ zend_class_implements (php_phongo_cursorid_ce TSRMLS_CC , 1 , zend_ce_serializable );
135
275
136
276
memcpy (& php_phongo_handler_cursorid , phongo_get_std_object_handlers (), sizeof (zend_object_handlers ));
137
277
php_phongo_handler_cursorid .get_debug_info = php_phongo_cursorid_get_debug_info ;
0 commit comments