Skip to content

Commit f317976

Browse files
authored
PHPC-1490: Add support for var_export() and __set_state() in CursorId.c (#1231)
1 parent 8c07222 commit f317976

13 files changed

+216
-20
lines changed

php_phongo_structs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ typedef struct {
6464
} php_phongo_cursor_t;
6565

6666
typedef struct {
67+
bool initialized;
6768
int64_t id;
69+
HashTable* properties;
6870
zend_object std;
6971
} php_phongo_cursorid_t;
7072

src/MongoDB/Cursor.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,9 @@ static void php_phongo_cursor_id_new_from_id(zval* object, int64_t cursorid) /*
124124

125125
object_init_ex(object, php_phongo_cursorid_ce);
126126

127-
intern = Z_CURSORID_OBJ_P(object);
128-
intern->id = cursorid;
127+
intern = Z_CURSORID_OBJ_P(object);
128+
intern->id = cursorid;
129+
intern->initialized = true;
129130
} /* }}} */
130131

131132
/* {{{ proto array MongoDB\Driver\Cursor::toArray()

src/MongoDB/CursorId.c

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ static bool php_phongo_cursorid_init_from_string(php_phongo_cursorid_t* intern,
3939
return false;
4040
}
4141

42-
intern->id = id;
42+
intern->id = id;
43+
intern->initialized = true;
4344
return true;
4445
} /* }}} */
4546

@@ -57,6 +58,61 @@ static bool php_phongo_cursorid_init_from_hash(php_phongo_cursorid_t* intern, Ha
5758
return false;
5859
} /* }}} */
5960

61+
static HashTable* php_phongo_cursorid_get_properties_hash(phongo_compat_object_handler_type* object, bool is_debug) /* {{{ */
62+
{
63+
php_phongo_cursorid_t* intern;
64+
HashTable* props;
65+
66+
intern = Z_OBJ_CURSORID(PHONGO_COMPAT_GET_OBJ(object));
67+
68+
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 2);
69+
70+
if (!intern->initialized) {
71+
return props;
72+
}
73+
74+
{
75+
zval value;
76+
77+
if (is_debug) {
78+
#if SIZEOF_ZEND_LONG == 4
79+
ZVAL_INT64_STRING(&value, intern->id);
80+
#else
81+
ZVAL_LONG(&value, intern->id);
82+
#endif
83+
} else {
84+
ZVAL_INT64_STRING(&value, intern->id);
85+
}
86+
zend_hash_str_update(props, "id", sizeof("id") - 1, &value);
87+
}
88+
89+
return props;
90+
} /* }}} */
91+
92+
/* {{{ proto MongoDB\Driver\CursorId MongoDB\Driver\CursorId::__set_state(array $properties)
93+
*/
94+
static PHP_METHOD(CursorId, __set_state)
95+
{
96+
zend_error_handling error_handling;
97+
php_phongo_cursorid_t* intern;
98+
HashTable* props;
99+
zval* array;
100+
101+
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
102+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
103+
zend_restore_error_handling(&error_handling);
104+
return;
105+
}
106+
zend_restore_error_handling(&error_handling);
107+
108+
object_init_ex(return_value, php_phongo_cursorid_ce);
109+
110+
intern = Z_CURSORID_OBJ_P(return_value);
111+
props = Z_ARRVAL_P(array);
112+
113+
php_phongo_cursorid_init_from_hash(intern, props);
114+
} /* }}} */
115+
60116
/* {{{ proto string MongoDB\Driver\CursorId::__toString()
61117
Returns the string representation of the CursorId */
62118
static PHP_METHOD(CursorId, __toString)
@@ -148,6 +204,10 @@ static PHP_METHOD(CursorId, unserialize)
148204
} /* }}} */
149205

150206
/* {{{ MongoDB\Driver\CursorId function entries */
207+
ZEND_BEGIN_ARG_INFO_EX(ai_CursorId___set_state, 0, 0, 1)
208+
ZEND_ARG_ARRAY_INFO(0, properties, 0)
209+
ZEND_END_ARG_INFO()
210+
151211
ZEND_BEGIN_ARG_INFO_EX(ai_CursorId_unserialize, 0, 0, 1)
152212
ZEND_ARG_INFO(0, serialized)
153213
ZEND_END_ARG_INFO()
@@ -157,6 +217,7 @@ ZEND_END_ARG_INFO()
157217

158218
static zend_function_entry php_phongo_cursorid_me[] = {
159219
/* clang-format off */
220+
PHP_ME(CursorId, __set_state, ai_CursorId___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
160221
PHP_ME(CursorId, __toString, ai_CursorId_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
161222
PHP_ME(CursorId, serialize, ai_CursorId_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
162223
PHP_ME(CursorId, unserialize, ai_CursorId_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
@@ -175,6 +236,11 @@ static void php_phongo_cursorid_free_object(zend_object* object) /* {{{ */
175236
php_phongo_cursorid_t* intern = Z_OBJ_CURSORID(object);
176237

177238
zend_object_std_dtor(&intern->std);
239+
240+
if (intern->properties) {
241+
zend_hash_destroy(intern->properties);
242+
FREE_HASHTABLE(intern->properties);
243+
}
178244
} /* }}} */
179245

180246
static zend_object* php_phongo_cursorid_create_object(zend_class_entry* class_type) /* {{{ */
@@ -193,24 +259,16 @@ static zend_object* php_phongo_cursorid_create_object(zend_class_entry* class_ty
193259

194260
static HashTable* php_phongo_cursorid_get_debug_info(phongo_compat_object_handler_type* object, int* is_temp) /* {{{ */
195261
{
196-
php_phongo_cursorid_t* intern;
197-
zval retval = ZVAL_STATIC_INIT;
198-
199262
*is_temp = 1;
200-
intern = Z_OBJ_CURSORID(PHONGO_COMPAT_GET_OBJ(object));
201-
202-
array_init(&retval);
203-
204-
#if SIZEOF_ZEND_LONG == 4
205-
ADD_ASSOC_INT64_AS_STRING(&retval, "id", intern->id);
206-
#else
207-
ADD_ASSOC_LONG_EX(&retval, "id", intern->id);
208-
#endif
209-
210-
return Z_ARRVAL(retval);
263+
return php_phongo_cursorid_get_properties_hash(object, true);
211264
} /* }}} */
212265
/* }}} */
213266

267+
static HashTable* php_phongo_cursorid_get_properties(phongo_compat_object_handler_type* object) /* {{{ */
268+
{
269+
return php_phongo_cursorid_get_properties_hash(object, false);
270+
} /* }}} */
271+
214272
void php_phongo_cursorid_init_ce(INIT_FUNC_ARGS) /* {{{ */
215273
{
216274
zend_class_entry ce;
@@ -224,6 +282,7 @@ void php_phongo_cursorid_init_ce(INIT_FUNC_ARGS) /* {{{ */
224282

225283
memcpy(&php_phongo_handler_cursorid, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
226284
php_phongo_handler_cursorid.get_debug_info = php_phongo_cursorid_get_debug_info;
285+
php_phongo_handler_cursorid.get_properties = php_phongo_cursorid_get_properties;
227286
php_phongo_handler_cursorid.free_obj = php_phongo_cursorid_free_object;
228287
php_phongo_handler_cursorid.offset = XtOffsetOf(php_phongo_cursorid_t, std);
229288
} /* }}} */

tests/cursorid/cursorid-001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
MongoDB\Driver\CursorID BSON serialization
2+
MongoDB\Driver\CursorId BSON serialization
33
--SKIPIF--
44
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
55
<?php skip_if_not_live(); ?>

tests/cursorid/cursorid-002.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
MongoDB\Driver\CursorID BSON serialization for killCursors command
2+
MongoDB\Driver\CursorId BSON serialization for killCursors command
33
--SKIPIF--
44
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
55
<?php skip_if_not_live(); ?>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
MongoDB\Driver\CursorId debug output
3+
--FILE--
4+
<?php
5+
6+
require_once __DIR__ . '/../utils/basic.inc';
7+
8+
$cursorId = unserialize('C:23:"MongoDB\Driver\CursorId":42:{a:1:{s:2:"id";s:19:"7250031947823432848";}}');
9+
10+
var_dump($cursorId);
11+
12+
?>
13+
===DONE===
14+
<?php exit(0); ?>
15+
--EXPECTF--
16+
object(MongoDB\Driver\CursorId)#%d (%d) {
17+
["id"]=>
18+
%rint\(|string\(19\) "|%r7250031947823432848%r"|\)%r
19+
}
20+
===DONE===
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
MongoDB\Driver\CursorId debug output on 32-bit platform
3+
--SKIPIF--
4+
<?php if (4 !== PHP_INT_SIZE) { die('skip Only for 32-bit platform'); } ?>
5+
--FILE--
6+
<?php
7+
8+
require_once __DIR__ . '/../utils/basic.inc';
9+
10+
$cursorId = unserialize('C:23:"MongoDB\Driver\CursorId":42:{a:1:{s:2:"id";s:19:"7250031947823432848";}}');
11+
12+
var_dump($cursorId);
13+
14+
?>
15+
===DONE===
16+
<?php exit(0); ?>
17+
--EXPECTF--
18+
object(MongoDB\Driver\CursorId)#%d (%d) {
19+
["id"]=>
20+
string(19) "7250031947823432848"
21+
}
22+
===DONE===
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
MongoDB\Driver\CursorId debug output on 64-bit platform
3+
--SKIPIF--
4+
<?php if (8 !== PHP_INT_SIZE) { die('skip Only for 64-bit platform'); } ?>
5+
--FILE--
6+
<?php
7+
8+
require_once __DIR__ . '/../utils/basic.inc';
9+
10+
$cursorId = unserialize('C:23:"MongoDB\Driver\CursorId":42:{a:1:{s:2:"id";s:19:"7250031947823432848";}}');
11+
12+
var_dump($cursorId);
13+
14+
?>
15+
===DONE===
16+
<?php exit(0); ?>
17+
--EXPECTF--
18+
object(MongoDB\Driver\CursorId)#%d (%d) {
19+
["id"]=>
20+
int(7250031947823432848)
21+
}
22+
===DONE===

tests/cursorid/cursorid-serialization-001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
MongoDB\Driver\CursorID serialization
2+
MongoDB\Driver\CursorId serialization
33
--FILE--
44
<?php
55

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
MongoDB\Driver\CursorId::__set_state()
3+
--FILE--
4+
<?php
5+
6+
var_export(MongoDB\Driver\CursorId::__set_state([
7+
'id' => '7250031947823432848',
8+
]));
9+
echo "\n";
10+
11+
?>
12+
===DONE===
13+
<?php exit(0); ?>
14+
--EXPECT--
15+
MongoDB\Driver\CursorId::__set_state(array(
16+
'id' => '7250031947823432848',
17+
))
18+
===DONE===

0 commit comments

Comments
 (0)